From f9720896b4c1ee5f1c63990baa5087594d890236 Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 17:42:36 +0100 Subject: [PATCH 1/9] Auto configure routes using a file name pattern --- package-lock.json | 26 ++++++++++++++++--- package.json | 2 ++ ...reate-course.route.ts => courses.route.ts} | 4 +-- src/apps/mooc_backend/routes/index.ts | 12 ++++++--- src/apps/mooc_backend/routes/status.route.ts | 4 +-- 5 files changed, 37 insertions(+), 11 deletions(-) rename src/apps/mooc_backend/routes/{create-course.route.ts => courses.route.ts} (69%) diff --git a/package-lock.json b/package-lock.json index 9b4198d..fe5fae9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -538,6 +538,11 @@ "@types/express": "*" } }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, "@types/express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", @@ -563,6 +568,16 @@ "integrity": "sha512-YSDqoBEWYGdNk53xSkkb6REaUaVSlIjxIAGjj/nbLzlZOit7kUU+nA2zC2qQkIVO4MQ+3zl4Sz7aw+kbpHHHUQ==", "dev": true }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/helmet": { "version": "0.0.44", "resolved": "https://registry.npmjs.org/@types/helmet/-/helmet-0.0.44.tgz", @@ -616,6 +631,11 @@ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + }, "@types/node": { "version": "11.13.20", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.20.tgz", @@ -3211,9 +3231,9 @@ "dev": true }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", diff --git a/package.json b/package.json index 8e0981d..2010b1b 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@types/convict": "^4.2.1", "@types/errorhandler": "0.0.32", "@types/express": "^4.17.1", + "@types/glob": "^7.1.1", "@types/helmet": "0.0.44", "@types/node": "~11.13.0", "@types/uuid": "^3.4.5", @@ -32,6 +33,7 @@ "copy": "^0.3.2", "errorhandler": "^1.5.1", "express": "^4.17.1", + "glob": "^7.1.6", "helmet": "^3.21.1", "http-status": "^1.3.2", "mandrill-api": "^1.0.45", diff --git a/src/apps/mooc_backend/routes/create-course.route.ts b/src/apps/mooc_backend/routes/courses.route.ts similarity index 69% rename from src/apps/mooc_backend/routes/create-course.route.ts rename to src/apps/mooc_backend/routes/courses.route.ts index cafd913..a90395c 100644 --- a/src/apps/mooc_backend/routes/create-course.route.ts +++ b/src/apps/mooc_backend/routes/courses.route.ts @@ -2,7 +2,7 @@ import { Express } from 'express'; import container from '../config/dependency-injection'; import CreateCourseController from '../controllers/CreateCourseController'; -export const createUserRoute = (app: Express) => { +export const register = (app: Express) => { const controller: CreateCourseController = container.get('Apps.mooc.controllers.CreateCourseController'); - app.put('/courses/:id', (req, res) => controller.create(req, res)); + app.put('/courses/:id', controller.create.bind(controller)); }; diff --git a/src/apps/mooc_backend/routes/index.ts b/src/apps/mooc_backend/routes/index.ts index 77959b7..844f646 100644 --- a/src/apps/mooc_backend/routes/index.ts +++ b/src/apps/mooc_backend/routes/index.ts @@ -1,8 +1,12 @@ import { Express } from 'express'; -import { statusRoute } from './status.route'; -import { createUserRoute } from './create-course.route'; +import glob from 'glob'; export function registerRoutes(app: Express) { - statusRoute(app); - createUserRoute(app); + const routes = glob.sync(__dirname + '/**/*.route.*'); + routes.map(route => register(route, app)); +} + +function register(routePath: string, app: Express) { + const route = require(routePath); + route.register(app); } diff --git a/src/apps/mooc_backend/routes/status.route.ts b/src/apps/mooc_backend/routes/status.route.ts index 28eeecb..8be98c0 100644 --- a/src/apps/mooc_backend/routes/status.route.ts +++ b/src/apps/mooc_backend/routes/status.route.ts @@ -2,7 +2,7 @@ import { Express } from 'express'; import container from '../config/dependency-injection'; import StatusController from '../controllers/StatusController'; -export const statusRoute = (app: Express) => { +export const register = (app: Express) => { const controller: StatusController = container.get('Apps.mooc.controllers.StatusController'); - app.get('/status', (req, res) => controller.create(req, res)); + app.get('/status', controller.create.bind(controller)); }; From 7c052b98a567d24f677023318250bc6b4e0e09d5 Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 17:45:24 +0100 Subject: [PATCH 2/9] Create the Contexts folder --- .../Mooc/Courses/application/CreateCourse.ts | 0 src/{ => Contexts}/Mooc/Courses/domain/Course.ts | 0 .../Mooc/Courses/domain/CourseRepository.ts | 0 .../Courses/infrastructure/FileCourseRepository.ts | 0 ...urses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo | Bin 0 -> 51 bytes .../Mooc/Courses/infrastructure/courses.id.repo | Bin 0 -> 57 bytes .../config/dependency-injection/application.yaml | 4 ++-- .../controllers/CreateCourseController.ts | 2 +- .../Mooc/Courses/application/CreateCourse.test.ts | 6 +++--- .../infrastructure/FileCourseRepository.test.ts | 4 ++-- 10 files changed, 8 insertions(+), 8 deletions(-) rename src/{ => Contexts}/Mooc/Courses/application/CreateCourse.ts (100%) rename src/{ => Contexts}/Mooc/Courses/domain/Course.ts (100%) rename src/{ => Contexts}/Mooc/Courses/domain/CourseRepository.ts (100%) rename src/{ => Contexts}/Mooc/Courses/infrastructure/FileCourseRepository.ts (100%) create mode 100644 src/Contexts/Mooc/Courses/infrastructure/courses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo create mode 100644 src/Contexts/Mooc/Courses/infrastructure/courses.id.repo diff --git a/src/Mooc/Courses/application/CreateCourse.ts b/src/Contexts/Mooc/Courses/application/CreateCourse.ts similarity index 100% rename from src/Mooc/Courses/application/CreateCourse.ts rename to src/Contexts/Mooc/Courses/application/CreateCourse.ts diff --git a/src/Mooc/Courses/domain/Course.ts b/src/Contexts/Mooc/Courses/domain/Course.ts similarity index 100% rename from src/Mooc/Courses/domain/Course.ts rename to src/Contexts/Mooc/Courses/domain/Course.ts diff --git a/src/Mooc/Courses/domain/CourseRepository.ts b/src/Contexts/Mooc/Courses/domain/CourseRepository.ts similarity index 100% rename from src/Mooc/Courses/domain/CourseRepository.ts rename to src/Contexts/Mooc/Courses/domain/CourseRepository.ts diff --git a/src/Mooc/Courses/infrastructure/FileCourseRepository.ts b/src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository.ts similarity index 100% rename from src/Mooc/Courses/infrastructure/FileCourseRepository.ts rename to src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository.ts diff --git a/src/Contexts/Mooc/Courses/infrastructure/courses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo b/src/Contexts/Mooc/Courses/infrastructure/courses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo new file mode 100644 index 0000000000000000000000000000000000000000..7eba887e6be10edd451b60a1c4ef99804e3cf6b1 GIT binary patch literal 51 zcmXqJU|?X1&rD%Z1u|08EE1Cq4J~vnQq0qIO)Qg>brX|PlXcB4QVmiJOcT>A3=$a_ E02`YN@Bjb+ literal 0 HcmV?d00001 diff --git a/src/Contexts/Mooc/Courses/infrastructure/courses.id.repo b/src/Contexts/Mooc/Courses/infrastructure/courses.id.repo new file mode 100644 index 0000000000000000000000000000000000000000..8630adac9c621e81f092e4184b10bc68d4dd3361 GIT binary patch literal 57 wcmcCyU|?X1&rD%p1~PyYQ+!@xZYl#SkOyWk#ix`OC6;97=P_^s#o!zU07=6Q761SM literal 0 HcmV?d00001 diff --git a/src/apps/mooc_backend/config/dependency-injection/application.yaml b/src/apps/mooc_backend/config/dependency-injection/application.yaml index c2904c6..cdaa454 100644 --- a/src/apps/mooc_backend/config/dependency-injection/application.yaml +++ b/src/apps/mooc_backend/config/dependency-injection/application.yaml @@ -1,10 +1,10 @@ services: Mooc.courses.CourseRepository: - class: ../../../../Mooc/Courses/infrastructure/FileCourseRepository + class: ../../../../Contexts/Mooc/Courses/infrastructure/FileCourseRepository arguments: [] Mooc.courses.CreateCourse: - class: ../../../../Mooc/Courses/application/CreateCourse + class: ../../../../Contexts/Mooc/Courses/application/CreateCourse arguments: ["@Mooc.courses.CourseRepository"] Apps.mooc.controllers.CreateCourseController: diff --git a/src/apps/mooc_backend/controllers/CreateCourseController.ts b/src/apps/mooc_backend/controllers/CreateCourseController.ts index 436c1f0..41b4a7d 100644 --- a/src/apps/mooc_backend/controllers/CreateCourseController.ts +++ b/src/apps/mooc_backend/controllers/CreateCourseController.ts @@ -1,5 +1,5 @@ import { Request, Response } from 'express'; -import CreateCourse from '../../../Mooc/Courses/application/CreateCourse'; +import CreateCourse from '../../../Contexts/Mooc/Courses/application/CreateCourse'; import httpStatus from 'http-status'; export default class CreateCourseController { diff --git a/tests/Mooc/Courses/application/CreateCourse.test.ts b/tests/Mooc/Courses/application/CreateCourse.test.ts index e7cc8dd..594ca4a 100644 --- a/tests/Mooc/Courses/application/CreateCourse.test.ts +++ b/tests/Mooc/Courses/application/CreateCourse.test.ts @@ -1,6 +1,6 @@ -import Course from '../../../../src/Mooc/Courses/domain/Course'; -import CreateCourse from '../../../../src/Mooc/Courses/application/CreateCourse'; -import CourseRepository from '../../../../src/Mooc/Courses/domain/CourseRepository'; +import Course from '../../../../src/Contexts/Mooc/Courses/domain/Course'; +import CreateCourse from '../../../../src/Contexts/Mooc/Courses/application/CreateCourse'; +import CourseRepository from '../../../../src/Contexts/Mooc/Courses/domain/CourseRepository'; describe('Create Course', () => { it('should create a valid course', async () => { diff --git a/tests/Mooc/Courses/infrastructure/FileCourseRepository.test.ts b/tests/Mooc/Courses/infrastructure/FileCourseRepository.test.ts index b68da3e..a5eed8a 100644 --- a/tests/Mooc/Courses/infrastructure/FileCourseRepository.test.ts +++ b/tests/Mooc/Courses/infrastructure/FileCourseRepository.test.ts @@ -1,5 +1,5 @@ -import Course from '../../../../src/Mooc/Courses/domain/Course'; -import FileCourseRepository from '../../../../src/Mooc/Courses/infrastructure/FileCourseRepository'; +import Course from '../../../../src/Contexts/Mooc/Courses/domain/Course'; +import FileCourseRepository from '../../../../src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository'; describe('Save Course', () => { it('should have a course', () => { From 88b9fbfc790a79a6eb21f1e8727a0daf06f353dd Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 18:15:40 +0100 Subject: [PATCH 3/9] Add the http verb to the name of the controllers --- .../config/dependency-injection/application.yaml | 8 ++++---- src/apps/mooc_backend/controllers/Controller.ts | 5 +++++ ...{CreateCourseController.ts => CoursePutController.ts} | 5 +++-- src/apps/mooc_backend/controllers/StatusController.ts | 8 -------- src/apps/mooc_backend/controllers/StatusGetController.ts | 9 +++++++++ src/apps/mooc_backend/routes/courses.route.ts | 6 +++--- src/apps/mooc_backend/routes/status.route.ts | 6 +++--- 7 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 src/apps/mooc_backend/controllers/Controller.ts rename src/apps/mooc_backend/controllers/{CreateCourseController.ts => CoursePutController.ts} (77%) delete mode 100644 src/apps/mooc_backend/controllers/StatusController.ts create mode 100644 src/apps/mooc_backend/controllers/StatusGetController.ts diff --git a/src/apps/mooc_backend/config/dependency-injection/application.yaml b/src/apps/mooc_backend/config/dependency-injection/application.yaml index cdaa454..37ae2cc 100644 --- a/src/apps/mooc_backend/config/dependency-injection/application.yaml +++ b/src/apps/mooc_backend/config/dependency-injection/application.yaml @@ -7,10 +7,10 @@ services: class: ../../../../Contexts/Mooc/Courses/application/CreateCourse arguments: ["@Mooc.courses.CourseRepository"] - Apps.mooc.controllers.CreateCourseController: - class: ../../controllers/CreateCourseController + Apps.mooc.controllers.CoursePutController: + class: ../../controllers/CoursePutController arguments: ["@Mooc.courses.CreateCourse"] - Apps.mooc.controllers.StatusController: - class: ../../controllers/StatusController + Apps.mooc.controllers.StatusGetController: + class: ../../controllers/StatusGetController arguments: [] diff --git a/src/apps/mooc_backend/controllers/Controller.ts b/src/apps/mooc_backend/controllers/Controller.ts new file mode 100644 index 0000000..4969747 --- /dev/null +++ b/src/apps/mooc_backend/controllers/Controller.ts @@ -0,0 +1,5 @@ +import {Request, Response} from 'express'; + +export default interface Controller { + run(req: Request, res: Response): Promise; +} diff --git a/src/apps/mooc_backend/controllers/CreateCourseController.ts b/src/apps/mooc_backend/controllers/CoursePutController.ts similarity index 77% rename from src/apps/mooc_backend/controllers/CreateCourseController.ts rename to src/apps/mooc_backend/controllers/CoursePutController.ts index 41b4a7d..b05fa25 100644 --- a/src/apps/mooc_backend/controllers/CreateCourseController.ts +++ b/src/apps/mooc_backend/controllers/CoursePutController.ts @@ -1,11 +1,12 @@ import { Request, Response } from 'express'; import CreateCourse from '../../../Contexts/Mooc/Courses/application/CreateCourse'; import httpStatus from 'http-status'; +import Controller from './Controller'; -export default class CreateCourseController { +export default class CoursePutController implements Controller { constructor(private createCourse: CreateCourse) {} - async create(req: Request, res: Response) { + async run(req: Request, res: Response) { const id: string = req.params.id; const name: string = req.body.name; const duration: string = req.body.duration; diff --git a/src/apps/mooc_backend/controllers/StatusController.ts b/src/apps/mooc_backend/controllers/StatusController.ts deleted file mode 100644 index 44c7c44..0000000 --- a/src/apps/mooc_backend/controllers/StatusController.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Request, Response } from 'express'; -import httpStatus from 'http-status'; - -export default class StatusController { - async create(req: Request, res: Response) { - res.status(httpStatus.OK).send(); - } -} diff --git a/src/apps/mooc_backend/controllers/StatusGetController.ts b/src/apps/mooc_backend/controllers/StatusGetController.ts new file mode 100644 index 0000000..62e219a --- /dev/null +++ b/src/apps/mooc_backend/controllers/StatusGetController.ts @@ -0,0 +1,9 @@ +import { Request, Response } from 'express'; +import httpStatus from 'http-status'; +import Controller from './Controller'; + +export default class StatusGetController implements Controller { + async run(req: Request, res: Response) { + res.status(httpStatus.OK).send(); + } +} diff --git a/src/apps/mooc_backend/routes/courses.route.ts b/src/apps/mooc_backend/routes/courses.route.ts index a90395c..ebbb8bf 100644 --- a/src/apps/mooc_backend/routes/courses.route.ts +++ b/src/apps/mooc_backend/routes/courses.route.ts @@ -1,8 +1,8 @@ import { Express } from 'express'; import container from '../config/dependency-injection'; -import CreateCourseController from '../controllers/CreateCourseController'; +import CreateCourseController from '../controllers/CoursePutController'; export const register = (app: Express) => { - const controller: CreateCourseController = container.get('Apps.mooc.controllers.CreateCourseController'); - app.put('/courses/:id', controller.create.bind(controller)); + const controller: CreateCourseController = container.get('Apps.mooc.controllers.CoursePutController'); + app.put('/courses/:id', controller.run.bind(controller)); }; diff --git a/src/apps/mooc_backend/routes/status.route.ts b/src/apps/mooc_backend/routes/status.route.ts index 8be98c0..e0ac7f1 100644 --- a/src/apps/mooc_backend/routes/status.route.ts +++ b/src/apps/mooc_backend/routes/status.route.ts @@ -1,8 +1,8 @@ import { Express } from 'express'; import container from '../config/dependency-injection'; -import StatusController from '../controllers/StatusController'; +import StatusController from '../controllers/StatusGetController'; export const register = (app: Express) => { - const controller: StatusController = container.get('Apps.mooc.controllers.StatusController'); - app.get('/status', controller.create.bind(controller)); + const controller: StatusController = container.get('Apps.mooc.controllers.StatusGetController'); + app.get('/status', controller.run.bind(controller)); }; From 0028b6e9d1c91c751519b6e72b443ca6937656fd Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 18:18:15 +0100 Subject: [PATCH 4/9] Ignore FileCourseRepository generated files --- .gitignore | 1 + ...urses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo | Bin 51 -> 0 bytes .../Mooc/Courses/infrastructure/courses.id.repo | Bin 57 -> 0 bytes .../controllers/CoursePutController.ts | 2 +- 4 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 src/Contexts/Mooc/Courses/infrastructure/courses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo delete mode 100644 src/Contexts/Mooc/Courses/infrastructure/courses.id.repo diff --git a/.gitignore b/.gitignore index 9a8b0a8..e049ccc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ dist/ .tmp +src/Contexts/Mooc/Courses/infrastructure/courses.* diff --git a/src/Contexts/Mooc/Courses/infrastructure/courses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo b/src/Contexts/Mooc/Courses/infrastructure/courses.ef8ac118-8d7f-49cc-abec-78e0d05af80a.repo deleted file mode 100644 index 7eba887e6be10edd451b60a1c4ef99804e3cf6b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51 zcmXqJU|?X1&rD%Z1u|08EE1Cq4J~vnQq0qIO)Qg>brX|PlXcB4QVmiJOcT>A3=$a_ E02`YN@Bjb+ diff --git a/src/Contexts/Mooc/Courses/infrastructure/courses.id.repo b/src/Contexts/Mooc/Courses/infrastructure/courses.id.repo deleted file mode 100644 index 8630adac9c621e81f092e4184b10bc68d4dd3361..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57 wcmcCyU|?X1&rD%p1~PyYQ+!@xZYl#SkOyWk#ix`OC6;97=P_^s#o!zU07=6Q761SM diff --git a/src/apps/mooc_backend/controllers/CoursePutController.ts b/src/apps/mooc_backend/controllers/CoursePutController.ts index b05fa25..3bd163b 100644 --- a/src/apps/mooc_backend/controllers/CoursePutController.ts +++ b/src/apps/mooc_backend/controllers/CoursePutController.ts @@ -14,7 +14,7 @@ export default class CoursePutController implements Controller { try { await this.createCourse.run(id, name, duration); } catch (e) { - res.status(500).json(e); + res.status(httpStatus.INTERNAL_SERVER_ERROR).json(e); } res.status(httpStatus.CREATED).send(); From d3d1c39d7f94d316e53f273fb4695e0f27de9314 Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 18:23:31 +0100 Subject: [PATCH 5/9] Handle specfic errors at the controller level --- src/Contexts/Mooc/Courses/domain/CourseAlreadyExists.ts | 5 +++++ src/apps/mooc_backend/controllers/CoursePutController.ts | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/Contexts/Mooc/Courses/domain/CourseAlreadyExists.ts diff --git a/src/Contexts/Mooc/Courses/domain/CourseAlreadyExists.ts b/src/Contexts/Mooc/Courses/domain/CourseAlreadyExists.ts new file mode 100644 index 0000000..df773ee --- /dev/null +++ b/src/Contexts/Mooc/Courses/domain/CourseAlreadyExists.ts @@ -0,0 +1,5 @@ +export default class CourseAlreadyExists extends Error { + constructor(courseId: string) { + super(`Course ${courseId} already exists`); + } +} diff --git a/src/apps/mooc_backend/controllers/CoursePutController.ts b/src/apps/mooc_backend/controllers/CoursePutController.ts index 3bd163b..4b8f447 100644 --- a/src/apps/mooc_backend/controllers/CoursePutController.ts +++ b/src/apps/mooc_backend/controllers/CoursePutController.ts @@ -2,6 +2,7 @@ import { Request, Response } from 'express'; import CreateCourse from '../../../Contexts/Mooc/Courses/application/CreateCourse'; import httpStatus from 'http-status'; import Controller from './Controller'; +import CourseAlreadyExists from '../../../Contexts/Mooc/Courses/domain/CourseAlreadyExists'; export default class CoursePutController implements Controller { constructor(private createCourse: CreateCourse) {} @@ -14,7 +15,13 @@ export default class CoursePutController implements Controller { try { await this.createCourse.run(id, name, duration); } catch (e) { - res.status(httpStatus.INTERNAL_SERVER_ERROR).json(e); + + if (e instanceof CourseAlreadyExists) { + res.status(httpStatus.BAD_REQUEST).send(e.message); + } else { + res.status(httpStatus.INTERNAL_SERVER_ERROR).json(e); + } + } res.status(httpStatus.CREATED).send(); From a43eef87bd9f51acc1cc4f25b41771dff91ed22c Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 18:37:21 +0100 Subject: [PATCH 6/9] Set as async the interfaces that will be async in the future implementations. Add Nullable type --- .../Mooc/Courses/application/CreateCourse.ts | 2 +- .../Mooc/Courses/domain/CourseRepository.ts | 5 +++-- .../infrastructure/FileCourseRepository.ts | 17 ++++++++++++----- src/Contexts/Shared/domain/Nullable.ts | 1 + 4 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 src/Contexts/Shared/domain/Nullable.ts diff --git a/src/Contexts/Mooc/Courses/application/CreateCourse.ts b/src/Contexts/Mooc/Courses/application/CreateCourse.ts index 6c15d02..253b1fb 100644 --- a/src/Contexts/Mooc/Courses/application/CreateCourse.ts +++ b/src/Contexts/Mooc/Courses/application/CreateCourse.ts @@ -11,6 +11,6 @@ export default class CreateCourse { async run(id: string, name: string, duration: string): Promise { const course = new Course(id, name, duration); - this.repository.save(course); + return this.repository.save(course); } } diff --git a/src/Contexts/Mooc/Courses/domain/CourseRepository.ts b/src/Contexts/Mooc/Courses/domain/CourseRepository.ts index 2dbe575..b0d574d 100644 --- a/src/Contexts/Mooc/Courses/domain/CourseRepository.ts +++ b/src/Contexts/Mooc/Courses/domain/CourseRepository.ts @@ -1,7 +1,8 @@ import Course from './Course'; +import { Nullable } from '../../../Shared/domain/Nullable'; export default interface CourseRepository { - save(course: Course): Promise | void; + save(course: Course): Promise; - search(id: string): Promise | Course; + search(id: string): Promise>; } diff --git a/src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository.ts b/src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository.ts index 75834cb..2b86743 100644 --- a/src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository.ts +++ b/src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository.ts @@ -1,17 +1,24 @@ import CourseRepository from '../domain/CourseRepository'; import Course from '../domain/Course'; -import * as fs from 'fs'; +import fs from 'fs'; import BSON from 'bson'; +import { Nullable } from '../../../Shared/domain/Nullable'; export default class FileCourseRepository implements CourseRepository { private FILE_PATH = `${__dirname}/courses`; - save(course: Course): void | Promise { - fs.writeFileSync(this.filePath(course.id), BSON.serialize(course)); + async save(course: Course): Promise { + const filePath = this.filePath(course.id); + const data = BSON.serialize(course); + + return fs.writeFileSync(filePath, data); } - search(id: string): Course { - return fs.existsSync(this.filePath(id)) ? BSON.deserialize(fs.readFileSync(this.filePath(id))) : null; + async search(id: string): Promise> { + const filePath = this.filePath(id); + const exists = fs.existsSync(filePath); + + return exists ? BSON.deserialize(fs.readFileSync(this.filePath(id))) : null; } private filePath(id: string): string { diff --git a/src/Contexts/Shared/domain/Nullable.ts b/src/Contexts/Shared/domain/Nullable.ts new file mode 100644 index 0000000..aa32b2d --- /dev/null +++ b/src/Contexts/Shared/domain/Nullable.ts @@ -0,0 +1 @@ +export type Nullable = T | null; From 0d6737ccd796cd37f37b8eb0851a6c414e7b8401 Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 18:38:52 +0100 Subject: [PATCH 7/9] Set strict mode at the TS compiler --- tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.json b/tsconfig.json index 9951b09..eb52c0a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "moduleResolution": "node", "sourceMap": false, "rootDir": ".", + "strict": true, "noEmit": false, "resolveJsonModule": true, "outDir": "./dist" From e777a3f86a299e15dd3be12b9cba66d0e7e34abd Mon Sep 17 00:00:00 2001 From: Fernando Vilas Maciel Date: Fri, 8 Nov 2019 18:41:29 +0100 Subject: [PATCH 8/9] Rename the application services for following codely convention --- .../application/{CreateCourse.ts => CourseCreator.ts} | 2 +- .../config/dependency-injection/application.yaml | 6 +++--- src/apps/mooc_backend/controllers/CoursePutController.ts | 6 +++--- .../{CreateCourse.test.ts => CourseCreator.test.ts} | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) rename src/Contexts/Mooc/Courses/application/{CreateCourse.ts => CourseCreator.ts} (91%) rename tests/Mooc/Courses/application/{CreateCourse.test.ts => CourseCreator.test.ts} (76%) diff --git a/src/Contexts/Mooc/Courses/application/CreateCourse.ts b/src/Contexts/Mooc/Courses/application/CourseCreator.ts similarity index 91% rename from src/Contexts/Mooc/Courses/application/CreateCourse.ts rename to src/Contexts/Mooc/Courses/application/CourseCreator.ts index 253b1fb..65170f3 100644 --- a/src/Contexts/Mooc/Courses/application/CreateCourse.ts +++ b/src/Contexts/Mooc/Courses/application/CourseCreator.ts @@ -1,7 +1,7 @@ import CourseRepository from '../domain/CourseRepository'; import Course from '../domain/Course'; -export default class CreateCourse { +export default class CourseCreator { private repository: CourseRepository; constructor(repository: CourseRepository) { diff --git a/src/apps/mooc_backend/config/dependency-injection/application.yaml b/src/apps/mooc_backend/config/dependency-injection/application.yaml index 37ae2cc..f7afcf1 100644 --- a/src/apps/mooc_backend/config/dependency-injection/application.yaml +++ b/src/apps/mooc_backend/config/dependency-injection/application.yaml @@ -3,13 +3,13 @@ services: class: ../../../../Contexts/Mooc/Courses/infrastructure/FileCourseRepository arguments: [] - Mooc.courses.CreateCourse: - class: ../../../../Contexts/Mooc/Courses/application/CreateCourse + Mooc.courses.CourseCreator: + class: ../../../../Contexts/Mooc/Courses/application/CourseCreator arguments: ["@Mooc.courses.CourseRepository"] Apps.mooc.controllers.CoursePutController: class: ../../controllers/CoursePutController - arguments: ["@Mooc.courses.CreateCourse"] + arguments: ["@Mooc.courses.CourseCreator"] Apps.mooc.controllers.StatusGetController: class: ../../controllers/StatusGetController diff --git a/src/apps/mooc_backend/controllers/CoursePutController.ts b/src/apps/mooc_backend/controllers/CoursePutController.ts index 4b8f447..61e77c5 100644 --- a/src/apps/mooc_backend/controllers/CoursePutController.ts +++ b/src/apps/mooc_backend/controllers/CoursePutController.ts @@ -1,11 +1,11 @@ import { Request, Response } from 'express'; -import CreateCourse from '../../../Contexts/Mooc/Courses/application/CreateCourse'; +import CourseCreator from '../../../Contexts/Mooc/Courses/application/CourseCreator'; import httpStatus from 'http-status'; import Controller from './Controller'; import CourseAlreadyExists from '../../../Contexts/Mooc/Courses/domain/CourseAlreadyExists'; export default class CoursePutController implements Controller { - constructor(private createCourse: CreateCourse) {} + constructor(private courseCreator: CourseCreator) {} async run(req: Request, res: Response) { const id: string = req.params.id; @@ -13,7 +13,7 @@ export default class CoursePutController implements Controller { const duration: string = req.body.duration; try { - await this.createCourse.run(id, name, duration); + await this.courseCreator.run(id, name, duration); } catch (e) { if (e instanceof CourseAlreadyExists) { diff --git a/tests/Mooc/Courses/application/CreateCourse.test.ts b/tests/Mooc/Courses/application/CourseCreator.test.ts similarity index 76% rename from tests/Mooc/Courses/application/CreateCourse.test.ts rename to tests/Mooc/Courses/application/CourseCreator.test.ts index 594ca4a..043a1ed 100644 --- a/tests/Mooc/Courses/application/CreateCourse.test.ts +++ b/tests/Mooc/Courses/application/CourseCreator.test.ts @@ -1,8 +1,8 @@ import Course from '../../../../src/Contexts/Mooc/Courses/domain/Course'; -import CreateCourse from '../../../../src/Contexts/Mooc/Courses/application/CreateCourse'; +import CourseCreator from '../../../../src/Contexts/Mooc/Courses/application/CourseCreator'; import CourseRepository from '../../../../src/Contexts/Mooc/Courses/domain/CourseRepository'; -describe('Create Course', () => { +describe('Course Creator', () => { it('should create a valid course', async () => { const save = jest.fn(); const repository: CourseRepository = { @@ -10,7 +10,7 @@ describe('Create Course', () => { search: jest.fn() }; - const createCourse = new CreateCourse(repository); + const createCourse = new CourseCreator(repository); const id = 'some-id'; const name = 'some-name'; From 7cd747e65640bd3e9755502db0709b164c42edcd Mon Sep 17 00:00:00 2001 From: rsaladocid Date: Wed, 13 Nov 2019 18:42:50 +0100 Subject: [PATCH 9/9] Refactor property access modifiers --- src/Contexts/Mooc/Courses/domain/Course.ts | 24 ++++++---------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/Contexts/Mooc/Courses/domain/Course.ts b/src/Contexts/Mooc/Courses/domain/Course.ts index a7a8432..2111d70 100644 --- a/src/Contexts/Mooc/Courses/domain/Course.ts +++ b/src/Contexts/Mooc/Courses/domain/Course.ts @@ -1,23 +1,11 @@ export default class Course { - private _id: string; - private _name: string; - private _duration: string; + readonly id: string; + readonly name: string; + readonly duration: string; constructor(id: string, name: string, duration: string) { - this._id = id; - this._name = name; - this._duration = duration; - } - - get id(): string { - return this._id; - } - - get name(): string { - return this._name; - } - - get duration(): string { - return this._duration; + this.id = id; + this.name = name; + this.duration = duration; } }