From e9b024f4df89572f2fbbaaa2eb294b4ced6600dc Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Sep 2021 11:35:27 +0200 Subject: [PATCH] Finished snippet controller --- src/controllers/snippets.ts | 103 +++++++++++++++++++++++++++++++++ src/middleware/errorHandler.ts | 17 ++++++ src/middleware/index.ts | 1 + src/middleware/requireBody.ts | 7 +++ src/routes/snippets.ts | 19 +++++- src/server.ts | 6 +- src/utils/ErrorResponse.ts | 8 +++ src/utils/index.ts | 1 + 8 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 src/middleware/errorHandler.ts create mode 100644 src/utils/ErrorResponse.ts diff --git a/src/controllers/snippets.ts b/src/controllers/snippets.ts index 5c045e1..eefe0cb 100644 --- a/src/controllers/snippets.ts +++ b/src/controllers/snippets.ts @@ -1,7 +1,13 @@ import { Request, Response, NextFunction } from 'express'; import { asyncWrapper } from '../middleware'; import { SnippetModel } from '../models'; +import { ErrorResponse } from '../utils'; +/** + * @description Create new snippet + * @route /api/snippets + * @request POST + */ export const createSnippet = asyncWrapper( async (req: Request, res: Response, next: NextFunction): Promise => { const snippet = await SnippetModel.create(req.body); @@ -11,3 +17,100 @@ export const createSnippet = asyncWrapper( }); } ); + +/** + * @description Get all snippets + * @route /api/snippets + * @request GET + */ +export const getAllSnippets = asyncWrapper( + async (req: Request, res: Response, next: NextFunction): Promise => { + const snippets = await SnippetModel.findAll(); + + res.status(200).json({ + data: snippets + }); + } +); + +/** + * @description Get single sinppet by id + * @route /api/snippets/:id + * @request GET + */ +export const getSnippet = asyncWrapper( + async (req: Request, res: Response, next: NextFunction): Promise => { + const snippet = await SnippetModel.findOne({ + where: { id: req.params.id } + }); + + if (!snippet) { + return next( + new ErrorResponse( + 404, + `Snippet with id of ${req.params.id} was not found` + ) + ); + } + + res.status(200).json({ + data: snippet + }); + } +); + +/** + * @description Update snippet + * @route /api/snippets/:id + * @request PUT + */ +export const updateSnippet = asyncWrapper( + async (req: Request, res: Response, next: NextFunction): Promise => { + let snippet = await SnippetModel.findOne({ + where: { id: req.params.id } + }); + + if (!snippet) { + return next( + new ErrorResponse( + 404, + `Snippet with id of ${req.params.id} was not found` + ) + ); + } + + snippet = await snippet.update(req.body); + + res.status(200).json({ + data: snippet + }); + } +); + +/** + * @description Delete snippet + * @route /api/snippets/:id + * @request DELETE + */ +export const deleteSnippet = asyncWrapper( + async (req: Request, res: Response, next: NextFunction): Promise => { + const snippet = await SnippetModel.findOne({ + where: { id: req.params.id } + }); + + if (!snippet) { + return next( + new ErrorResponse( + 404, + `Snippet with id of ${req.params.id} was not found` + ) + ); + } + + await snippet.destroy(); + + res.status(200).json({ + data: {} + }); + } +); diff --git a/src/middleware/errorHandler.ts b/src/middleware/errorHandler.ts new file mode 100644 index 0000000..bdc7591 --- /dev/null +++ b/src/middleware/errorHandler.ts @@ -0,0 +1,17 @@ +import { Request, Response, NextFunction } from 'express'; +import { ErrorResponse, Logger } from '../utils'; + +const logger = new Logger('errorHandler'); + +export const errorHandler = ( + err: ErrorResponse, + req: Request, + res: Response, + next: NextFunction +) => { + logger.log(err.message, 'ERROR'); + + res.status(err.statusCode || 500).json({ + error: err.message || 'Internal Server Error' + }); +}; diff --git a/src/middleware/index.ts b/src/middleware/index.ts index 6a139d4..ebcbe86 100644 --- a/src/middleware/index.ts +++ b/src/middleware/index.ts @@ -1,2 +1,3 @@ export * from './asyncWrapper'; export * from './requireBody'; +export * from './errorHandler'; diff --git a/src/middleware/requireBody.ts b/src/middleware/requireBody.ts index 5995890..1b1d143 100644 --- a/src/middleware/requireBody.ts +++ b/src/middleware/requireBody.ts @@ -1,4 +1,5 @@ import { Request, Response, NextFunction } from 'express'; +import { ErrorResponse } from '../utils'; export const requireBody = (...fields: string[]) => @@ -12,5 +13,11 @@ export const requireBody = } }); + if (missingKeys.length > 0) { + return next( + new ErrorResponse(400, `These fields are required: ${missingKeys}`) + ); + } + next(); }; diff --git a/src/routes/snippets.ts b/src/routes/snippets.ts index 9fa2e09..0687b3d 100644 --- a/src/routes/snippets.ts +++ b/src/routes/snippets.ts @@ -1,7 +1,22 @@ import { Router } from 'express'; -import { createSnippet } from '../controllers/snippets'; +import { + createSnippet, + deleteSnippet, + getAllSnippets, + getSnippet, + updateSnippet +} from '../controllers/snippets'; import { requireBody } from '../middleware'; export const snippetRouter = Router(); -snippetRouter.route('/').post(requireBody('title', 'language'), createSnippet); +snippetRouter + .route('/') + .post(requireBody('title', 'language'), createSnippet) + .get(getAllSnippets); + +snippetRouter + .route('/:id') + .get(getSnippet) + .put(updateSnippet) + .delete(deleteSnippet); diff --git a/src/server.ts b/src/server.ts index 996470b..9734917 100644 --- a/src/server.ts +++ b/src/server.ts @@ -2,6 +2,7 @@ import dotenv from 'dotenv'; import express from 'express'; import { Logger } from './utils'; import { connectDB } from './db'; +import { errorHandler } from './middleware'; // Routers import { snippetRouter } from './routes/snippets'; @@ -11,7 +12,7 @@ dotenv.config({ path: './src/config/.env' }); const app = express(); const logger = new Logger('server'); -const PORT = process.env.PORT; +const PORT = process.env.PORT || 5000; // App config app.use(express.json()); @@ -19,6 +20,9 @@ app.use(express.json()); // Routes app.use('/api/snippets', snippetRouter); +// Error handler +app.use(errorHandler); + (async () => { await connectDB(); diff --git a/src/utils/ErrorResponse.ts b/src/utils/ErrorResponse.ts new file mode 100644 index 0000000..6213e23 --- /dev/null +++ b/src/utils/ErrorResponse.ts @@ -0,0 +1,8 @@ +export class ErrorResponse extends Error { + public statusCode: number; + + constructor(statusCode: number, msg: string) { + super(msg); + this.statusCode = statusCode; + } +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 58309e3..e59e2fd 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1,2 @@ export * from './Logger'; +export * from './ErrorResponse';