From 0906924309f6597f636490522cb987dff41da44d Mon Sep 17 00:00:00 2001 From: Matheus Sanchez Date: Wed, 24 Jan 2024 16:51:09 -0300 Subject: [PATCH 1/3] get user route and spliting routes --- src/app.ts | 3 ++ src/controller/user/getUserById.ts | 25 +++++++++++++++++ src/controller/user/routes.ts | 7 +++++ .../in-memory-db/inMemoryUserRepository.ts | 28 ++++++++++++++++++- src/server.ts | 20 ++++--------- 5 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 src/controller/user/getUserById.ts create mode 100644 src/controller/user/routes.ts diff --git a/src/app.ts b/src/app.ts index 8dfd916..63acde4 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,3 +1,6 @@ import fastify from 'fastify' +import { userRoutes } from './controller/user/routes' + export const app = fastify() +app.register(userRoutes) diff --git a/src/controller/user/getUserById.ts b/src/controller/user/getUserById.ts new file mode 100644 index 0000000..9ae3593 --- /dev/null +++ b/src/controller/user/getUserById.ts @@ -0,0 +1,25 @@ +import { FastifyReply, FastifyRequest } from 'fastify' +import { InMemoryUserRepository } from '../../repositories/in-memory-db/inMemoryUserRepository' +import { z } from 'zod' +import { GetUserByIdUseCase } from '../../use-cases/getUserByIdUseCase' + +export async function getUserById( + request: FastifyRequest, + response: FastifyReply, +) { + + const userRepository = new InMemoryUserRepository() + const getUserByIdUseCase = new GetUserByIdUseCase(userRepository) + + const getUserByIdBodySchema = z.object({ + id: z.string().uuid(), + }) + + const { id } = getUserByIdBodySchema.parse(request.params) + + const { user } = await getUserByIdUseCase.execute({ + id, + }) + + return response.status(200).send({ user }) +} diff --git a/src/controller/user/routes.ts b/src/controller/user/routes.ts new file mode 100644 index 0000000..8d0c98a --- /dev/null +++ b/src/controller/user/routes.ts @@ -0,0 +1,7 @@ +import { FastifyInstance } from 'fastify' +import { getUserById } from './getUserById' + +export async function userRoutes(app: FastifyInstance) { + + app.get('/user/:id', getUserById) +} diff --git a/src/repositories/in-memory-db/inMemoryUserRepository.ts b/src/repositories/in-memory-db/inMemoryUserRepository.ts index cd22f4b..e9f34d2 100644 --- a/src/repositories/in-memory-db/inMemoryUserRepository.ts +++ b/src/repositories/in-memory-db/inMemoryUserRepository.ts @@ -5,6 +5,31 @@ import { randomUUID } from 'crypto' export class InMemoryUserRepository implements UserRepository { private db: User[] = [] + + // This is a way to test our controllers without necessartralyy add the + // db repository; Once the program starts, one user is added to User[] and + // you can get http://localhost:3333/user/9600de4f-8d18-4e69-ba7a-ed7fa210618d + // to check the routes; + + // this constructor will be delete later; + constructor(){ + + const email = 'johndoe2@email.com' + const name = 'John' + const surname = 'Doe' + const password_hash = 'password_hash' + const id = '9600de4f-8d18-4e69-ba7a-ed7fa210618d' + + this.create({ + id, + name, + surname, + email, + password_hash, + }) + + } + async findByEmail(email: string): Promise { const User = this.db.find((User) => User.email === email) @@ -28,13 +53,14 @@ export class InMemoryUserRepository implements UserRepository { // create in a in-memory database is just used to help us on unit tests; // that's why is not in our interface :) async create({ + id, name, surname, email, password_hash, }: Prisma.UserCreateInput) { const user: User = { - id: randomUUID(), + id: (id == undefined) ? randomUUID() : id, name, surname, diff --git a/src/server.ts b/src/server.ts index b2d2440..0b030b1 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,19 +1,9 @@ import { app } from './app' import { env } from './env' -import { prisma } from './lib/prisma' -app.get('/', async (req, res) => { - const user = await prisma.user.create({ - data: { - name: 'Max', - surname: 'Sousa', - email: 'max@email.com', - password_hash: '123', - } +app.listen({ + port: env.PORT, }) - res.send('Lets go ForΓ§a da Natureza!') -}) - -app.listen(env.PORT, () => { - console.log('πŸ”₯πŸ”₯πŸ”₯ HTTP Server Running πŸ”₯πŸ”₯πŸ”₯') -}) \ No newline at end of file + .then(() => { + console.log('πŸ”₯πŸ”₯πŸ”₯ HTTP Server Running πŸ”₯πŸ”₯πŸ”₯') + }) \ No newline at end of file From 822dc2ba3158f4f5f51387de6afbc634f35b3789 Mon Sep 17 00:00:00 2001 From: Matheus Sanchez Date: Wed, 24 Jan 2024 16:51:37 -0300 Subject: [PATCH 2/3] Handling ZZod Errors --- src/app.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/app.ts b/src/app.ts index 63acde4..73ab25d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,6 +1,25 @@ import fastify from 'fastify' import { userRoutes } from './controller/user/routes' +import { env } from './env' +import { ZodError } from 'zod' export const app = fastify() app.register(userRoutes) + + + +app.setErrorHandler((error, _, response) => { + if (env.NODE_ENV !== 'production') { + console.error(error) + } else { + // TODO: log this error somewhere + } + if (error instanceof ZodError) { + return response + .status(400) + .send({ message: 'Validation Error', issues: error.format() }) + } + + return response.status(500).send({ message: 'Internal Server Error' }) +}) \ No newline at end of file From 700a8e8d79771e797f284167630e169ee1e22e10 Mon Sep 17 00:00:00 2001 From: Matheus Sanchez Date: Wed, 24 Jan 2024 17:04:49 -0300 Subject: [PATCH 3/3] Route Get user by email --- src/controller/user/getUserByEmail.ts | 25 +++++++++++++++++++++++++ src/controller/user/routes.ts | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 src/controller/user/getUserByEmail.ts diff --git a/src/controller/user/getUserByEmail.ts b/src/controller/user/getUserByEmail.ts new file mode 100644 index 0000000..e784433 --- /dev/null +++ b/src/controller/user/getUserByEmail.ts @@ -0,0 +1,25 @@ +import { FastifyReply, FastifyRequest } from 'fastify' +import { InMemoryUserRepository } from '../../repositories/in-memory-db/inMemoryUserRepository' +import { z } from 'zod' +import { GetUserByEmailUseCase } from '../../use-cases/getUserByEmailUseCase' + +export async function getUserByEmail( + request: FastifyRequest, + response: FastifyReply, +) { + + const userRepository = new InMemoryUserRepository() + const getUserByEmailUseCase = new GetUserByEmailUseCase(userRepository) + + const getUserByEmailBodySchema = z.object({ + email: z.string().email(), + }) + + const { email } = getUserByEmailBodySchema.parse(request.query) + + const { user } = await getUserByEmailUseCase.execute({ + email, + }) + + return response.status(200).send({ user }) +} diff --git a/src/controller/user/routes.ts b/src/controller/user/routes.ts index 8d0c98a..f69b683 100644 --- a/src/controller/user/routes.ts +++ b/src/controller/user/routes.ts @@ -1,7 +1,9 @@ import { FastifyInstance } from 'fastify' import { getUserById } from './getUserById' +import { getUserByEmail } from './getUserByEmail' export async function userRoutes(app: FastifyInstance) { app.get('/user/:id', getUserById) + app.get('/user', getUserByEmail) }