Created
March 29, 2024 18:35
-
-
Save sudomaxime/64b76432de378f92d2e524fc2bd38d57 to your computer and use it in GitHub Desktop.
Simple example of procedural approach to clean architecture without interfaces
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as z from 'zod'; | |
// ENTITY ======================================================== | |
const userEntityPresenter = z.object({ | |
id: z.number(), | |
name: z.string(), | |
email: z.string() | |
}); | |
type UserEntity = z.infer<typeof userEntityPresenter>; | |
// DTOS ======================================================== | |
const createUserInput = z.object({ | |
name: z.string().max(255), | |
email: z.string().email().max(255) | |
}) | |
type UserCreationDTO = z.infer<typeof createUserInput>; | |
// REPOSITORY ======================================================== | |
class UserRepository { | |
createUser (input: UserCreationDTO): UserEntity { | |
return { | |
id: 1, | |
...input | |
} | |
} | |
} | |
// Base case ========================================================= | |
abstract class Case { | |
constructor() { | |
this.execute = this.execute.bind(this); | |
} | |
abstract execute(input: unknown): unknown; | |
} | |
// Case ============================================================== | |
type Dependency = { | |
userRepository: UserRepository; | |
} | |
class CreateUserCase extends Case { | |
readonly payload = createUserInput; | |
readonly presenter = userEntityPresenter; | |
constructor(readonly dependencies: Dependency) { | |
super(); | |
} | |
/** | |
* @throws {z.ZodIssue} - If the input is invalid | |
*/ | |
async execute (input: UserCreationDTO): Promise<UserEntity> { | |
const values = this.payload.parse(input); | |
const user = this.dependencies.userRepository.createUser(values); | |
return this.presenter.parse(user); | |
} | |
} | |
const userRepository = new UserRepository(); | |
export const createUser = new CreateUserCase({userRepository}).execute; | |
// EXPRESS CONTROLLER ================================================ | |
export function createUserController (req, res, next) { | |
const user = createUser(req.body); | |
res.json(user); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment