From cabd9fae01a08716d60d096b4a1ef54e5fd7ca8c Mon Sep 17 00:00:00 2001 From: Hunter Date: Tue, 2 Apr 2024 01:38:04 +1100 Subject: [PATCH] reorganize project --- backend/src/controllers/news.controller.ts | 27 +++++++-------- .../src/controllers/research.controller.ts | 27 +++++++-------- backend/src/controllers/util/validate.ts | 0 backend/src/errors/HTTPErrors.ts | 33 +++++++++++++++++++ backend/src/index.ts | 10 +++--- .../repositories/memory/MemoryRepository.ts | 4 ++- backend/src/routes/news.router.ts | 17 +++++++--- backend/src/routes/research.router.ts | 17 +++++++--- 8 files changed, 94 insertions(+), 41 deletions(-) create mode 100644 backend/src/controllers/util/validate.ts create mode 100644 backend/src/errors/HTTPErrors.ts diff --git a/backend/src/controllers/news.controller.ts b/backend/src/controllers/news.controller.ts index 7caddbf3..3f9044bd 100644 --- a/backend/src/controllers/news.controller.ts +++ b/backend/src/controllers/news.controller.ts @@ -1,20 +1,21 @@ import { RequestHandler } from "express"; import { DB } from "../repositories/repository"; +import { BadRequestError, NotFoundError } from "../errors/HTTPErrors"; -export const getAllNews: RequestHandler = async (_, res, next) => { - try { - res.status(200).json(await DB.getAllNews()) - } catch (err) { - console.error(err) - next(err) +export default class NewsController { + static getAllNews: RequestHandler = async (req, res, next) => { + res.json(await DB.getAllNews()) } -} -export const getNewsById: RequestHandler = async (req, res, next) => { - try { - res.status(200).json(await DB.getNewsById(Number(req.params.id))) - } catch (err) { - console.error(err) - next(err) + static getNewsById: RequestHandler = async (req, res, next) => { + if (!("id" in req.params)) throw new BadRequestError() + const id: number = Number(req.params.id) + if (isNaN(id)) throw new BadRequestError() + + const n = await DB.getNewsById(id) + if (!n) throw new NotFoundError(`News article with id ${req.params.id} does not exist.`) + + res.json(await DB.getNewsById(id)) + next() } } diff --git a/backend/src/controllers/research.controller.ts b/backend/src/controllers/research.controller.ts index b15c8e4a..a6ce8822 100644 --- a/backend/src/controllers/research.controller.ts +++ b/backend/src/controllers/research.controller.ts @@ -1,20 +1,21 @@ import { RequestHandler } from "express"; import { DB } from "../repositories/repository"; +import { BadRequestError, NotFoundError } from "../errors/HTTPErrors"; -export const getAllResearch: RequestHandler = async (_, res, next) => { - try { - res.status(200).json(DB.getAllResearch()) - } catch (err) { - console.error(err) - next(err) +export default class ResearchController { + static getAllResearch: RequestHandler = async (req, res, next) => { + res.json(await DB.getAllResearch()) } -} -export const getResearchById: RequestHandler = async (req, res, next) => { - try { - res.status(200).json(DB.getResearchById(Number(req.params.id))) - } catch (err) { - console.error(err) - next(err) + static getResearchById: RequestHandler = async (req, res, next) => { + if (!("id" in req.params)) throw new BadRequestError() + const id: number = Number(req.params.id) + if (isNaN(id)) throw new BadRequestError() + + const n = await DB.getResearchById(id) + if (!n) throw new NotFoundError(`Research article with id ${req.params.id} does not exist.`) + + res.json(await DB.getResearchById(id)) + next() } } diff --git a/backend/src/controllers/util/validate.ts b/backend/src/controllers/util/validate.ts new file mode 100644 index 00000000..e69de29b diff --git a/backend/src/errors/HTTPErrors.ts b/backend/src/errors/HTTPErrors.ts new file mode 100644 index 00000000..c8d53eb7 --- /dev/null +++ b/backend/src/errors/HTTPErrors.ts @@ -0,0 +1,33 @@ +abstract class HTTPError extends Error { + public status: number + + protected constructor (status: number) { + super() + this.status = status + this.name = "HTTPError" + } +} + +export class NotFoundError extends HTTPError { + constructor (message?: string) { + super(404) + this.message = message?? "Not Found" + this.name = this.status.toString() + } +} + +export class UnauthorizedError extends HTTPError { + constructor(message?: string) { + super(401) + this.message = message ?? "Unauthorized" + this.name = this.status.toString() + } +} + +export class BadRequestError extends HTTPError { + constructor(message?: string) { + super(400) + this.message = message ?? "Bad Request" + this.name = this.status.toString() + } +} diff --git a/backend/src/index.ts b/backend/src/index.ts index 50bd6412..5b062c87 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,19 +1,21 @@ import express, { Express, Request, Response } from "express"; import dotenv from "dotenv"; -import { newsRouter, newsURL } from "./routes/news.router"; -import { researchRouter, researchURL } from "./routes/research.router"; +import NewsRouter from "./routes/news.router"; +import ResearchRouter from "./routes/research.router"; dotenv.config() const app: Express = express() const port = process.env.PORT || 3000 +app.use(express.json()) + app.get("/", (req: Request, res: Response) => { res.json({ message: "ok" }) }) -app.use(`/content/${newsURL}`, newsRouter) -app.use(`/content/${researchURL}`, researchRouter) +app.use(NewsRouter.url, NewsRouter.router()) +app.use(ResearchRouter.url, ResearchRouter.router()) app.listen(port, () => { diff --git a/backend/src/repositories/memory/MemoryRepository.ts b/backend/src/repositories/memory/MemoryRepository.ts index a1089620..972a5f4e 100644 --- a/backend/src/repositories/memory/MemoryRepository.ts +++ b/backend/src/repositories/memory/MemoryRepository.ts @@ -1,10 +1,12 @@ -import { Article, User, IArticle } from "@aapc/types"; +import { Article, IArticle, User } from "@aapc/types"; import IRepository from "../IRepository"; import users from "./data/users.json" import news from "./data/news.json" import researches from "./data/researches.json" import { Nullable } from "../../util/types"; +// interface IArticleInput extends Omit {} + export default class MemoryRepository implements IRepository { private readonly users: User[] private readonly news: Article[] diff --git a/backend/src/routes/news.router.ts b/backend/src/routes/news.router.ts index 0c803094..2c1d9f49 100644 --- a/backend/src/routes/news.router.ts +++ b/backend/src/routes/news.router.ts @@ -1,8 +1,15 @@ import express, { Router } from "express"; -import { getAllNews, getNewsById } from "../controllers/news.controller"; +import NewsController from "../controllers/news.controller"; -export const newsRouter: Router = express.Router() -export const newsURL = "news" +export default class NewsRouter { + static url = "/content/news" -newsRouter.get("/", getAllNews) -newsRouter.get("/:id", getNewsById) + static router (): Router { + const router = express.Router() + + router.get("/", NewsController.getAllNews) + router.get("/:id", NewsController.getNewsById) + + return router + } +} diff --git a/backend/src/routes/research.router.ts b/backend/src/routes/research.router.ts index 6a8fefed..fe9883e7 100644 --- a/backend/src/routes/research.router.ts +++ b/backend/src/routes/research.router.ts @@ -1,8 +1,15 @@ import express, { Router } from "express"; -import { getAllResearch, getResearchById } from "../controllers/research.controller"; +import ResearchController from "../controllers/research.controller"; -export const researchRouter: Router = express.Router() -export const researchURL = "research" +export default class ResearchRouter { + static url = "/content/research" -researchRouter.get("/", getAllResearch) -researchRouter.get("/:id", getResearchById) + static router(): Router { + const router = express.Router() + + router.get("/", ResearchController.getAllResearch) + router.get("/:id", ResearchController.getResearchById) + + return router + } +}