From 776c2489515cf568be8ffd3d2a5e453481225d94 Mon Sep 17 00:00:00 2001 From: Leonardo Lodi Date: Tue, 18 Jun 2024 14:17:13 +0100 Subject: [PATCH 1/4] add get, post, delete and put http methods for users, films and books databases --- src/routers/books.js | 53 ++++++++++++++++++++++++++++++++++++++++++-- src/routers/films.js | 53 ++++++++++++++++++++++++++++++++++++++++++++ src/routers/users.js | 53 ++++++++++++++++++++++++++++++++++++++++++++ src/server.js | 6 ++++- 4 files changed, 162 insertions(+), 3 deletions(-) diff --git a/src/routers/books.js b/src/routers/books.js index 18b9a7c..e41d248 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,4 +1,53 @@ -// Import data here... +const epxress = require("express") +const { books } = require("../../data") +const router = epxress.Router() +router.get('/', (req, res) => { + res.json({ + books: books + }) +}) -// Write routes here... +router.post('/', (req, res) => { + const book = {id: books.length + 1, ...req.body} + + books.push(book) + + res.status(201).json({ + book: book + }) +}) + +router.get('/:id', (req, res) => { + const id = Number(req.params.id) + const book = books.find(b => b.id === id) + + res.json({ + book: book + }) +}) + +router.delete('/:id', (req, res) => { + const id = Number(req.params.id) + const book = books.find(b => b.id === id) + + books.splice(books.indexOf(book), 1) + + res.json({ + book: book + }) +}) + +router.put('/:id', (req, res) => { + const id = Number(req.params.id) + const book = books.find(b => b.id === id) + const updatedBook = { id: book.id, ...req.body} + + books.splice(books.indexOf(book), 1, updatedBook) + + res.json({ + book: updatedBook + }) +}) + +module.exports = router \ No newline at end of file diff --git a/src/routers/films.js b/src/routers/films.js index e69de29..ed577df 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -0,0 +1,53 @@ +const express = require("express") +const { films } = require("../../data") +const router = express.Router() + +router.get('/', (req, res) => { + res.json({ + films: films + }) +}) + +router.post('/', (req, res) => { + const film = { id: films.length + 1, ...req.body} + + films.push(film) + + res.status(201).json({ + film: film + }) +}) + +router.get('/:id', (req, res) => { + const id = Number(req.params.id) + const film = films.find(f => f.id === id) + + res.json({ + film: film + }) +}) + +router.delete('/:id', (req, res) => { + const id = Number(req.params.id) + const film = films.find(f => f.id === id) + + films.splice(films.indexOf(film), 1) + + res.json({ + film: film + }) +}) + +router.put('/:id', (req, res) => { + const id = Number(req.params.id) + const film = films.find(f => f.id === id) + const updatedFilm = { id: film.id, ...req.body } + + films.splice(films.indexOf(film), 1, updatedFilm) + + res.json({ + film: updatedFilm + }) +}) + +module.exports = router diff --git a/src/routers/users.js b/src/routers/users.js index e69de29..fc56bfe 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -0,0 +1,53 @@ +const express = require("express") +const { users } = require("../../data") +const router = express.Router() + +router.get('/', (req, res) => { + res.json({ + users: users + }) +}) + +router.post('/', (req, res) => { + const user = { id: users.length + 1, ...req.body} + + users.push(user) + + res.status(201).json({ + user: user + }) +}) + +router.get('/:id', (req, res) => { + const id = Number(req.params.id) + const user = users.find(u => u.id === id) + + res.json({ + user: user + }) +}) + +router.delete('/:id', (req, res) => { + const id = Number(req.params.id) + const user = users.find(u => u.id === id) + + users.splice(users.indexOf(user), 1) + + res.json({ + user: user + }) +}) + +router.put('/:id', (req, res) => { + const id = Number(req.params.id) + const user = users.find(u => u.id === id) + const updatedUser = { id: user.id, ...req.body } + + users.splice(users.indexOf(user), 1, updatedUser) + + res.json({ + user: updatedUser + }) +}) + +module.exports = router diff --git a/src/server.js b/src/server.js index 715321f..292f9a5 100644 --- a/src/server.js +++ b/src/server.js @@ -11,8 +11,12 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users"); +const filmsRouter = require("./routers/films"); +const booksRouter = require("./routers/books"); // ADD ROUTERS TO APP - +app.use('/users', usersRouter) +app.use('/films', filmsRouter) +app.use('/books', booksRouter) module.exports = app From 5d388f45b78f6d11083b2ad3f896770308f2b4e5 Mon Sep 17 00:00:00 2001 From: Leonardo Lodi Date: Tue, 18 Jun 2024 17:33:16 +0100 Subject: [PATCH 2/4] add patch, error handling and get query methods --- src/errors/DataNotFound.js | 3 ++ src/errors/ExistingDataError.js | 3 ++ src/errors/MissingDataError.js | 3 ++ src/routers/books.js | 89 +++++++++++++++++++++++++++++++++ src/routers/films.js | 76 ++++++++++++++++++++++++++++ src/routers/users.js | 36 +++++++++++++ src/server.js | 25 +++++++++ 7 files changed, 235 insertions(+) create mode 100644 src/errors/DataNotFound.js create mode 100644 src/errors/ExistingDataError.js create mode 100644 src/errors/MissingDataError.js diff --git a/src/errors/DataNotFound.js b/src/errors/DataNotFound.js new file mode 100644 index 0000000..f4ac51d --- /dev/null +++ b/src/errors/DataNotFound.js @@ -0,0 +1,3 @@ +class DataNotFound extends Error {} + +module.exports = DataNotFound diff --git a/src/errors/ExistingDataError.js b/src/errors/ExistingDataError.js new file mode 100644 index 0000000..9001278 --- /dev/null +++ b/src/errors/ExistingDataError.js @@ -0,0 +1,3 @@ +class ExistingDataError extends Error {} + +module.exports = ExistingDataError diff --git a/src/errors/MissingDataError.js b/src/errors/MissingDataError.js new file mode 100644 index 0000000..14ddd5e --- /dev/null +++ b/src/errors/MissingDataError.js @@ -0,0 +1,3 @@ +class MissingDataError extends Error {} + +module.exports = MissingDataError \ No newline at end of file diff --git a/src/routers/books.js b/src/routers/books.js index e41d248..cf129a0 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,5 +1,8 @@ const epxress = require("express") const { books } = require("../../data") +const MissingDataError = require("../errors/MissingDataError") +const ExistingDataError = require("../errors/ExistingDataError") +const DataNotFound = require("../errors/DataNotFound") const router = epxress.Router() router.get('/', (req, res) => { @@ -9,6 +12,16 @@ router.get('/', (req, res) => { }) router.post('/', (req, res) => { + if (!req.body.title || !req.body.type || !req.body.author) { + throw new MissingDataError('Missing fields in request body') + } + + const existingBook = books.find(b => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError('A book with the provided title already exists') + } + const book = {id: books.length + 1, ...req.body} books.push(book) @@ -22,6 +35,10 @@ router.get('/:id', (req, res) => { const id = Number(req.params.id) const book = books.find(b => b.id === id) + if (!book) { + throw new DataNotFound('A book the provided ID does not exist') + } + res.json({ book: book }) @@ -31,6 +48,10 @@ router.delete('/:id', (req, res) => { const id = Number(req.params.id) const book = books.find(b => b.id === id) + if (!book) { + throw new DataNotFound('A book the provided ID does not exist') + } + books.splice(books.indexOf(book), 1) res.json({ @@ -39,10 +60,25 @@ router.delete('/:id', (req, res) => { }) router.put('/:id', (req, res) => { + if (!req.body.title || !req.body.type || !req.body.author) { + throw new MissingDataError('Missing fields in request body') + } + const id = Number(req.params.id) const book = books.find(b => b.id === id) + + if (!book) { + throw new DataNotFound('A book the provided ID does not exist') + } + const updatedBook = { id: book.id, ...req.body} + const existingBook = books.find(b => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError('A book with the provided title already exists') + } + books.splice(books.indexOf(book), 1, updatedBook) res.json({ @@ -50,4 +86,57 @@ router.put('/:id', (req, res) => { }) }) +router.patch('/:id', (req, res) => { + if (!req.body.title && !req.body.type && !req.body.author) { + throw new MissingDataError('Missing fields in request body') + } + + const id = Number(req.params.id) + const book = books.find(b => b.id === id) + + if (!book) { + throw new DataNotFound('A book the provided ID does not exist') + } + + const existingBook = books.find(b => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError('A book with the provided title already exists') + } + + let updatedBook = {} + + if (req.body.title && !req.body.type && !req.body.author) { + updatedBook = { id: book.id, ...req.body, type: book.type, author: book.author} + } + + if (req.body.title && req.body.type && !req.body.author) { + updatedBook = { id: book.id, ...req.body, author: book.author} + } + + if (req.body.title && !req.body.type && req.body.author) { + updatedBook = { id: book.id, title: req.body.title, type: book.type, author: req.body.author} + } + + if (!req.body.title && req.body.type && !req.body.author) { + updatedBook = { id: book.id, title: book.title, ...req.body, author: book.author} + } + + if (!req.body.title && req.body.type && req.body.author) { + updatedBook = { id: book.id, title: book.title, ...req.body} + } + + if (!req.body.title && !req.body.type && req.body.author) { + updatedBook = { id: book.id, title: book.title, type: book.type, ...req.body} + } + + if (req.body.title && req.body.type && req.body.author) { + updatedBook = { id: book.id, ...req.body} + } + + res.json({ + book: updatedBook + }) +}) + module.exports = router \ No newline at end of file diff --git a/src/routers/films.js b/src/routers/films.js index ed577df..5fb7799 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -1,14 +1,36 @@ const express = require("express") const { films } = require("../../data") +const MissingDataError = require("../errors/MissingDataError") +const ExistingDataError = require("../errors/ExistingDataError") +const DataNotFound = require("../errors/DataNotFound") const router = express.Router() router.get('/', (req, res) => { + if (req.query.director) { + const directorName = req.query.director.split(' ').join('').toLowerCase() + const directorFilms = films.filter(f => f.director.split(' ').join('').toLowerCase() === directorName) + + return res.json({ + films: directorFilms + }) + } + res.json({ films: films }) }) router.post('/', (req, res) => { + if (!req.body.title || !req.body.director) { + throw new MissingDataError('Missing fields in request body') + } + + const existingFilm = films.find(f => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError('A film with the provided title already exists') + } + const film = { id: films.length + 1, ...req.body} films.push(film) @@ -22,6 +44,10 @@ router.get('/:id', (req, res) => { const id = Number(req.params.id) const film = films.find(f => f.id === id) + if (!film) { + throw new DataNotFound('A film with provided ID does not exist') + } + res.json({ film: film }) @@ -31,6 +57,10 @@ router.delete('/:id', (req, res) => { const id = Number(req.params.id) const film = films.find(f => f.id === id) + if (!film) { + throw new DataNotFound('A film with provided ID does not exist') + } + films.splice(films.indexOf(film), 1) res.json({ @@ -41,6 +71,17 @@ router.delete('/:id', (req, res) => { router.put('/:id', (req, res) => { const id = Number(req.params.id) const film = films.find(f => f.id === id) + + if (!film) { + throw new DataNotFound('A film with provided ID does not exist') + } + + const existingFilm = films.find(f => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError('A film with the provided title already exists') + } + const updatedFilm = { id: film.id, ...req.body } films.splice(films.indexOf(film), 1, updatedFilm) @@ -50,4 +91,39 @@ router.put('/:id', (req, res) => { }) }) +router.patch('/:id', (req, res) => { + if (!req.body.title && !req.body.director) { + throw new MissingDataError('Missing fields in the request body') + } + + const id = Number(req.params.id) + const film = films.find(f => f.id === id) + + if (!film) { + throw new DataNotFound('A film with provided ID does not exist') + } + + const existingFilm = films.find(f => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError('A film with the provided title already exists') + } + + let updatedFilm = {} + + if (!req.body.title && req.body.director) { + updatedFilm = { id: film.id, title: film.title, ...req.body } + } + + if (req.body.title && !req.body.director) { + updatedFilm = { id: film.id, ...req.body, director: film.director } + } + + films.splice(films.indexOf(film), 1, updatedFilm) + + res.json({ + film: updatedFilm + }) +}) + module.exports = router diff --git a/src/routers/users.js b/src/routers/users.js index fc56bfe..0d3848a 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -1,5 +1,8 @@ const express = require("express") const { users } = require("../../data") +const MissingDataError = require("../errors/MissingDataError") +const ExistingDataError = require("../errors/ExistingDataError") +const DataNotFound = require("../errors/DataNotFound") const router = express.Router() router.get('/', (req, res) => { @@ -9,6 +12,16 @@ router.get('/', (req, res) => { }) router.post('/', (req, res) => { + if (!req.body.email) { + throw new MissingDataError('Missing fields in request body') + } + + const existingUser = users.find(u => u.email === req.body.email) + + if (existingUser) { + throw new ExistingDataError('A user with the provided email already exists') + } + const user = { id: users.length + 1, ...req.body} users.push(user) @@ -21,6 +34,10 @@ router.post('/', (req, res) => { router.get('/:id', (req, res) => { const id = Number(req.params.id) const user = users.find(u => u.id === id) + + if (!user) { + throw new DataNotFound('A user with the provided ID does not exist') + } res.json({ user: user @@ -31,6 +48,10 @@ router.delete('/:id', (req, res) => { const id = Number(req.params.id) const user = users.find(u => u.id === id) + if (!user) { + throw new DataNotFound('A user with the provided ID does not exist') + } + users.splice(users.indexOf(user), 1) res.json({ @@ -39,8 +60,23 @@ router.delete('/:id', (req, res) => { }) router.put('/:id', (req, res) => { + if (!req.body.email) { + throw new MissingDataError('Missing fields in request body') + } + const id = Number(req.params.id) const user = users.find(u => u.id === id) + + if (!user) { + throw new DataNotFound('A user with the provided ID does not exist') + } + + const existingUser = users.find(u => u.email === req.body.email) + + if (existingUser) { + throw new ExistingDataError('A user with the provided email already exists') + } + const updatedUser = { id: user.id, ...req.body } users.splice(users.indexOf(user), 1, updatedUser) diff --git a/src/server.js b/src/server.js index 292f9a5..d33b41b 100644 --- a/src/server.js +++ b/src/server.js @@ -19,4 +19,29 @@ app.use('/users', usersRouter) app.use('/films', filmsRouter) app.use('/books', booksRouter) +// ADD ERRORS CLASSES +const MissingDataError = require("./errors/MissingDataError"); +const ExistingDataError = require("./errors/ExistingDataError"); +const DataNotFound = require("./errors/DataNotFound"); + +app.use((error, req, res, next) => { + if (error instanceof MissingDataError) { + return res.status(400).json({ + error: error.message + }) + } + + if (error instanceof ExistingDataError) { + return res.status(409).json({ + error: error.message + }) + } + + if (error instanceof DataNotFound) { + return res.status(404).json({ + error: error.message + }) + } +}) + module.exports = app From 0c9b3c2f747daa48cf52a2671146ac1770c3ceb6 Mon Sep 17 00:00:00 2001 From: Leonardo Lodi Date: Tue, 18 Jun 2024 18:28:37 +0100 Subject: [PATCH 3/4] do mvc: add controllers directory for each endpoint --- src/controllers/booksControllers.js | 173 ++++++++++++++++++++++++++++ src/controllers/filmsControllers.js | 142 +++++++++++++++++++++++ src/controllers/usersControllers.js | 97 ++++++++++++++++ src/index.js | 8 +- src/routers/books.js | 152 +++--------------------- src/routers/films.js | 133 +++------------------ src/routers/users.js | 92 ++------------- src/server.js | 66 +++++------ 8 files changed, 492 insertions(+), 371 deletions(-) create mode 100644 src/controllers/booksControllers.js create mode 100644 src/controllers/filmsControllers.js create mode 100644 src/controllers/usersControllers.js diff --git a/src/controllers/booksControllers.js b/src/controllers/booksControllers.js new file mode 100644 index 0000000..8a8181a --- /dev/null +++ b/src/controllers/booksControllers.js @@ -0,0 +1,173 @@ +const { books } = require("../../data") +const MissingDataError = require("../errors/MissingDataError") +const ExistingDataError = require("../errors/ExistingDataError") +const DataNotFound = require("../errors/DataNotFound") + +const getBooks = (req, res) => { + res.json({ + books: books, + }) +} + +const postBook = (req, res) => { + if (!req.body.title || !req.body.type || !req.body.author) { + throw new MissingDataError("Missing fields in request body") + } + + const existingBook = books.find((b) => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError( + "A book with the provided title already exists" + ) + } + + const book = { id: books.length + 1, ...req.body } + + books.push(book) + + res.status(201).json({ + book: book, + }) +} + +const getBookById = (req, res) => { + const id = Number(req.params.id) + const book = books.find((b) => b.id === id) + + if (!book) { + throw new DataNotFound("A book the provided ID does not exist") + } + + res.json({ + book: book, + }) +} + +const deleteBook = (req, res) => { + const id = Number(req.params.id) + const book = books.find((b) => b.id === id) + + if (!book) { + throw new DataNotFound("A book the provided ID does not exist") + } + + books.splice(books.indexOf(book), 1) + + res.json({ + book: book, + }) +} + +const updateBook = (req, res) => { + if (!req.body.title || !req.body.type || !req.body.author) { + throw new MissingDataError("Missing fields in request body") + } + + const id = Number(req.params.id) + const book = books.find((b) => b.id === id) + + if (!book) { + throw new DataNotFound("A book the provided ID does not exist") + } + + const updatedBook = { id: book.id, ...req.body } + + const existingBook = books.find((b) => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError( + "A book with the provided title already exists" + ) + } + + books.splice(books.indexOf(book), 1, updatedBook) + + res.json({ + book: updatedBook, + }) +} + +const patchBook = (req, res) => { + if (!req.body.title && !req.body.type && !req.body.author) { + throw new MissingDataError("Missing fields in request body") + } + + const id = Number(req.params.id) + const book = books.find((b) => b.id === id) + + if (!book) { + throw new DataNotFound("A book the provided ID does not exist") + } + + const existingBook = books.find((b) => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError( + "A book with the provided title already exists" + ) + } + + let updatedBook = {} + + if (req.body.title && !req.body.type && !req.body.author) { + updatedBook = { + id: book.id, + ...req.body, + type: book.type, + author: book.author, + } + } + + if (req.body.title && req.body.type && !req.body.author) { + updatedBook = { id: book.id, ...req.body, author: book.author } + } + + if (req.body.title && !req.body.type && req.body.author) { + updatedBook = { + id: book.id, + title: req.body.title, + type: book.type, + author: req.body.author, + } + } + + if (!req.body.title && req.body.type && !req.body.author) { + updatedBook = { + id: book.id, + title: book.title, + ...req.body, + author: book.author, + } + } + + if (!req.body.title && req.body.type && req.body.author) { + updatedBook = { id: book.id, title: book.title, ...req.body } + } + + if (!req.body.title && !req.body.type && req.body.author) { + updatedBook = { + id: book.id, + title: book.title, + type: book.type, + ...req.body, + } + } + + if (req.body.title && req.body.type && req.body.author) { + updatedBook = { id: book.id, ...req.body } + } + + res.json({ + book: updatedBook, + }) +} + +module.exports = { + getBooks, + postBook, + getBookById, + deleteBook, + updateBook, + patchBook, +} diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js new file mode 100644 index 0000000..0439ab3 --- /dev/null +++ b/src/controllers/filmsControllers.js @@ -0,0 +1,142 @@ +const { films } = require("../../data") +const MissingDataError = require("../errors/MissingDataError") +const ExistingDataError = require("../errors/ExistingDataError") +const DataNotFound = require("../errors/DataNotFound") + +const getFilms = (req, res) => { + if (req.query.director) { + const directorName = req.query.director.split(" ").join("").toLowerCase() + const directorFilms = films.filter( + (f) => f.director.split(" ").join("").toLowerCase() === directorName + ) + + return res.json({ + films: directorFilms, + }) + } + + res.json({ + films: films, + }) +} + +const postFilm = (req, res) => { + if (!req.body.title || !req.body.director) { + throw new MissingDataError("Missing fields in request body") + } + + const existingFilm = films.find((f) => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError( + "A film with the provided title already exists" + ) + } + + const film = { id: films.length + 1, ...req.body } + + films.push(film) + + res.status(201).json({ + film: film, + }) +} + +const getFilmById = (req, res) => { + const id = Number(req.params.id) + const film = films.find((f) => f.id === id) + + if (!film) { + throw new DataNotFound("A film with provided ID does not exist") + } + + res.json({ + film: film, + }) +} + +const deleteFilm = (req, res) => { + const id = Number(req.params.id) + const film = films.find((f) => f.id === id) + + if (!film) { + throw new DataNotFound("A film with provided ID does not exist") + } + + films.splice(films.indexOf(film), 1) + + res.json({ + film: film, + }) +} + +const updateFilm = (req, res) => { + const id = Number(req.params.id) + const film = films.find((f) => f.id === id) + + if (!film) { + throw new DataNotFound("A film with provided ID does not exist") + } + + const existingFilm = films.find((f) => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError( + "A film with the provided title already exists" + ) + } + + const updatedFilm = { id: film.id, ...req.body } + + films.splice(films.indexOf(film), 1, updatedFilm) + + res.json({ + film: updatedFilm, + }) +} + +const patchFilm = (req, res) => { + if (!req.body.title && !req.body.director) { + throw new MissingDataError("Missing fields in the request body") + } + + const id = Number(req.params.id) + const film = films.find((f) => f.id === id) + + if (!film) { + throw new DataNotFound("A film with provided ID does not exist") + } + + const existingFilm = films.find((f) => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError( + "A film with the provided title already exists" + ) + } + + let updatedFilm = {} + + if (!req.body.title && req.body.director) { + updatedFilm = { id: film.id, title: film.title, ...req.body } + } + + if (req.body.title && !req.body.director) { + updatedFilm = { id: film.id, ...req.body, director: film.director } + } + + films.splice(films.indexOf(film), 1, updatedFilm) + + res.json({ + film: updatedFilm, + }) +} + +module.exports = { + getFilms, + postFilm, + getFilmById, + deleteFilm, + updateFilm, + patchFilm, +} diff --git a/src/controllers/usersControllers.js b/src/controllers/usersControllers.js new file mode 100644 index 0000000..ee30369 --- /dev/null +++ b/src/controllers/usersControllers.js @@ -0,0 +1,97 @@ +const { users } = require("../../data") +const MissingDataError = require("../errors/MissingDataError") +const ExistingDataError = require("../errors/ExistingDataError") +const DataNotFound = require("../errors/DataNotFound") + +const getUsers = (req, res) => { + res.json({ + users: users, + }) +} + +const postUser = (req, res) => { + if (!req.body.email) { + throw new MissingDataError("Missing fields in request body") + } + + const existingUser = users.find((u) => u.email === req.body.email) + + if (existingUser) { + throw new ExistingDataError( + "A user with the provided email already exists" + ) + } + + const user = { id: users.length + 1, ...req.body } + + users.push(user) + + res.status(201).json({ + user: user, + }) +} + +const getUserById = (req, res) => { + const id = Number(req.params.id) + const user = users.find((u) => u.id === id) + + if (!user) { + throw new DataNotFound("A user with the provided ID does not exist") + } + + res.json({ + user: user, + }) +} + +const deleteUser = (req, res) => { + const id = Number(req.params.id) + const user = users.find((u) => u.id === id) + + if (!user) { + throw new DataNotFound("A user with the provided ID does not exist") + } + + users.splice(users.indexOf(user), 1) + + res.json({ + user: user, + }) +} + +const updateUser = (req, res) => { + if (!req.body.email) { + throw new MissingDataError("Missing fields in request body") + } + + const id = Number(req.params.id) + const user = users.find((u) => u.id === id) + + if (!user) { + throw new DataNotFound("A user with the provided ID does not exist") + } + + const existingUser = users.find((u) => u.email === req.body.email) + + if (existingUser) { + throw new ExistingDataError( + "A user with the provided email already exists" + ) + } + + const updatedUser = { id: user.id, ...req.body } + + users.splice(users.indexOf(user), 1, updatedUser) + + res.json({ + user: updatedUser, + }) +} + +module.exports = { + getUsers, + postUser, + getUserById, + deleteUser, + updateUser, +} diff --git a/src/index.js b/src/index.js index c16707f..8c97d0b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,8 @@ /* REQUIRE APP */ -const app = require('./server.js') -const port = 3030; +const app = require("./server.js") +const port = 3030 /* START SERVER */ app.listen(port, () => { - console.log(`Server is running on http://localhost:${port}/`); -}); + console.log(`Server is running on http://localhost:${port}/`) +}) diff --git a/src/routers/books.js b/src/routers/books.js index cf129a0..47e5d44 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,142 +1,24 @@ -const epxress = require("express") -const { books } = require("../../data") -const MissingDataError = require("../errors/MissingDataError") -const ExistingDataError = require("../errors/ExistingDataError") -const DataNotFound = require("../errors/DataNotFound") -const router = epxress.Router() +const express = require("express") +const { + postBook, + getBookById, + deleteBook, + updateBook, + patchBook, + getBooks, +} = require("../controllers/booksControllers") +const router = express.Router() -router.get('/', (req, res) => { - res.json({ - books: books - }) -}) +router.get("/", getBooks) -router.post('/', (req, res) => { - if (!req.body.title || !req.body.type || !req.body.author) { - throw new MissingDataError('Missing fields in request body') - } +router.post("/", postBook) - const existingBook = books.find(b => b.title === req.body.title) +router.get("/:id", getBookById) - if (existingBook) { - throw new ExistingDataError('A book with the provided title already exists') - } +router.delete("/:id", deleteBook) - const book = {id: books.length + 1, ...req.body} +router.put("/:id", updateBook) - books.push(book) +router.patch("/:id", patchBook) - res.status(201).json({ - book: book - }) -}) - -router.get('/:id', (req, res) => { - const id = Number(req.params.id) - const book = books.find(b => b.id === id) - - if (!book) { - throw new DataNotFound('A book the provided ID does not exist') - } - - res.json({ - book: book - }) -}) - -router.delete('/:id', (req, res) => { - const id = Number(req.params.id) - const book = books.find(b => b.id === id) - - if (!book) { - throw new DataNotFound('A book the provided ID does not exist') - } - - books.splice(books.indexOf(book), 1) - - res.json({ - book: book - }) -}) - -router.put('/:id', (req, res) => { - if (!req.body.title || !req.body.type || !req.body.author) { - throw new MissingDataError('Missing fields in request body') - } - - const id = Number(req.params.id) - const book = books.find(b => b.id === id) - - if (!book) { - throw new DataNotFound('A book the provided ID does not exist') - } - - const updatedBook = { id: book.id, ...req.body} - - const existingBook = books.find(b => b.title === req.body.title) - - if (existingBook) { - throw new ExistingDataError('A book with the provided title already exists') - } - - books.splice(books.indexOf(book), 1, updatedBook) - - res.json({ - book: updatedBook - }) -}) - -router.patch('/:id', (req, res) => { - if (!req.body.title && !req.body.type && !req.body.author) { - throw new MissingDataError('Missing fields in request body') - } - - const id = Number(req.params.id) - const book = books.find(b => b.id === id) - - if (!book) { - throw new DataNotFound('A book the provided ID does not exist') - } - - const existingBook = books.find(b => b.title === req.body.title) - - if (existingBook) { - throw new ExistingDataError('A book with the provided title already exists') - } - - let updatedBook = {} - - if (req.body.title && !req.body.type && !req.body.author) { - updatedBook = { id: book.id, ...req.body, type: book.type, author: book.author} - } - - if (req.body.title && req.body.type && !req.body.author) { - updatedBook = { id: book.id, ...req.body, author: book.author} - } - - if (req.body.title && !req.body.type && req.body.author) { - updatedBook = { id: book.id, title: req.body.title, type: book.type, author: req.body.author} - } - - if (!req.body.title && req.body.type && !req.body.author) { - updatedBook = { id: book.id, title: book.title, ...req.body, author: book.author} - } - - if (!req.body.title && req.body.type && req.body.author) { - updatedBook = { id: book.id, title: book.title, ...req.body} - } - - if (!req.body.title && !req.body.type && req.body.author) { - updatedBook = { id: book.id, title: book.title, type: book.type, ...req.body} - } - - if (req.body.title && req.body.type && req.body.author) { - updatedBook = { id: book.id, ...req.body} - } - - res.json({ - book: updatedBook - }) -}) - -module.exports = router \ No newline at end of file +module.exports = router diff --git a/src/routers/films.js b/src/routers/films.js index 5fb7799..ef297a1 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -1,129 +1,24 @@ const express = require("express") -const { films } = require("../../data") -const MissingDataError = require("../errors/MissingDataError") -const ExistingDataError = require("../errors/ExistingDataError") -const DataNotFound = require("../errors/DataNotFound") +const { + getFilms, + postFilm, + getFilmById, + deleteFilm, + updateFilm, + patchFilm, +} = require("../controllers/filmsControllers") const router = express.Router() -router.get('/', (req, res) => { - if (req.query.director) { - const directorName = req.query.director.split(' ').join('').toLowerCase() - const directorFilms = films.filter(f => f.director.split(' ').join('').toLowerCase() === directorName) +router.get("/", getFilms) - return res.json({ - films: directorFilms - }) - } +router.post("/", postFilm) - res.json({ - films: films - }) -}) +router.get("/:id", getFilmById) -router.post('/', (req, res) => { - if (!req.body.title || !req.body.director) { - throw new MissingDataError('Missing fields in request body') - } +router.delete("/:id", deleteFilm) - const existingFilm = films.find(f => f.title === req.body.title) +router.put("/:id", updateFilm) - if (existingFilm) { - throw new ExistingDataError('A film with the provided title already exists') - } - - const film = { id: films.length + 1, ...req.body} - - films.push(film) - - res.status(201).json({ - film: film - }) -}) - -router.get('/:id', (req, res) => { - const id = Number(req.params.id) - const film = films.find(f => f.id === id) - - if (!film) { - throw new DataNotFound('A film with provided ID does not exist') - } - - res.json({ - film: film - }) -}) - -router.delete('/:id', (req, res) => { - const id = Number(req.params.id) - const film = films.find(f => f.id === id) - - if (!film) { - throw new DataNotFound('A film with provided ID does not exist') - } - - films.splice(films.indexOf(film), 1) - - res.json({ - film: film - }) -}) - -router.put('/:id', (req, res) => { - const id = Number(req.params.id) - const film = films.find(f => f.id === id) - - if (!film) { - throw new DataNotFound('A film with provided ID does not exist') - } - - const existingFilm = films.find(f => f.title === req.body.title) - - if (existingFilm) { - throw new ExistingDataError('A film with the provided title already exists') - } - - const updatedFilm = { id: film.id, ...req.body } - - films.splice(films.indexOf(film), 1, updatedFilm) - - res.json({ - film: updatedFilm - }) -}) - -router.patch('/:id', (req, res) => { - if (!req.body.title && !req.body.director) { - throw new MissingDataError('Missing fields in the request body') - } - - const id = Number(req.params.id) - const film = films.find(f => f.id === id) - - if (!film) { - throw new DataNotFound('A film with provided ID does not exist') - } - - const existingFilm = films.find(f => f.title === req.body.title) - - if (existingFilm) { - throw new ExistingDataError('A film with the provided title already exists') - } - - let updatedFilm = {} - - if (!req.body.title && req.body.director) { - updatedFilm = { id: film.id, title: film.title, ...req.body } - } - - if (req.body.title && !req.body.director) { - updatedFilm = { id: film.id, ...req.body, director: film.director } - } - - films.splice(films.indexOf(film), 1, updatedFilm) - - res.json({ - film: updatedFilm - }) -}) +router.patch("/:id", patchFilm) module.exports = router diff --git a/src/routers/users.js b/src/routers/users.js index 0d3848a..886d1f4 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -1,89 +1,21 @@ const express = require("express") -const { users } = require("../../data") -const MissingDataError = require("../errors/MissingDataError") -const ExistingDataError = require("../errors/ExistingDataError") -const DataNotFound = require("../errors/DataNotFound") +const { + getUsers, + postUser, + getUserById, + deleteUser, + updateUser, +} = require("../controllers/usersControllers") const router = express.Router() -router.get('/', (req, res) => { - res.json({ - users: users - }) -}) +router.get("/", getUsers) -router.post('/', (req, res) => { - if (!req.body.email) { - throw new MissingDataError('Missing fields in request body') - } +router.post("/", postUser) - const existingUser = users.find(u => u.email === req.body.email) +router.get("/:id", getUserById) - if (existingUser) { - throw new ExistingDataError('A user with the provided email already exists') - } +router.delete("/:id", deleteUser) - const user = { id: users.length + 1, ...req.body} - - users.push(user) - - res.status(201).json({ - user: user - }) -}) - -router.get('/:id', (req, res) => { - const id = Number(req.params.id) - const user = users.find(u => u.id === id) - - if (!user) { - throw new DataNotFound('A user with the provided ID does not exist') - } - - res.json({ - user: user - }) -}) - -router.delete('/:id', (req, res) => { - const id = Number(req.params.id) - const user = users.find(u => u.id === id) - - if (!user) { - throw new DataNotFound('A user with the provided ID does not exist') - } - - users.splice(users.indexOf(user), 1) - - res.json({ - user: user - }) -}) - -router.put('/:id', (req, res) => { - if (!req.body.email) { - throw new MissingDataError('Missing fields in request body') - } - - const id = Number(req.params.id) - const user = users.find(u => u.id === id) - - if (!user) { - throw new DataNotFound('A user with the provided ID does not exist') - } - - const existingUser = users.find(u => u.email === req.body.email) - - if (existingUser) { - throw new ExistingDataError('A user with the provided email already exists') - } - - const updatedUser = { id: user.id, ...req.body } - - users.splice(users.indexOf(user), 1, updatedUser) - - res.json({ - user: updatedUser - }) -}) +router.put("/:id", updateUser) module.exports = router diff --git a/src/server.js b/src/server.js index d33b41b..ff5fa94 100644 --- a/src/server.js +++ b/src/server.js @@ -1,47 +1,47 @@ -const express = require("express"); -const app = express(); +const express = require("express") +const app = express() -const cors = require("cors"); -const morgan = require("morgan"); +const cors = require("cors") +const morgan = require("morgan") // SETUP MIDDLEWARE -app.use(cors()); -app.use(express.json()); -app.use(morgan("dev")); +app.use(cors()) +app.use(express.json()) +app.use(morgan("dev")) // REQUIRE ROUTERS -const usersRouter = require("./routers/users"); -const filmsRouter = require("./routers/films"); -const booksRouter = require("./routers/books"); +const usersRouter = require("./routers/users") +const filmsRouter = require("./routers/films") +const booksRouter = require("./routers/books") // ADD ROUTERS TO APP -app.use('/users', usersRouter) -app.use('/films', filmsRouter) -app.use('/books', booksRouter) +app.use("/users", usersRouter) +app.use("/films", filmsRouter) +app.use("/books", booksRouter) // ADD ERRORS CLASSES -const MissingDataError = require("./errors/MissingDataError"); -const ExistingDataError = require("./errors/ExistingDataError"); -const DataNotFound = require("./errors/DataNotFound"); +const MissingDataError = require("./errors/MissingDataError") +const ExistingDataError = require("./errors/ExistingDataError") +const DataNotFound = require("./errors/DataNotFound") app.use((error, req, res, next) => { - if (error instanceof MissingDataError) { - return res.status(400).json({ - error: error.message - }) - } - - if (error instanceof ExistingDataError) { - return res.status(409).json({ - error: error.message - }) - } - - if (error instanceof DataNotFound) { - return res.status(404).json({ - error: error.message - }) - } + if (error instanceof MissingDataError) { + return res.status(400).json({ + error: error.message, + }) + } + + if (error instanceof ExistingDataError) { + return res.status(409).json({ + error: error.message, + }) + } + + if (error instanceof DataNotFound) { + return res.status(404).json({ + error: error.message, + }) + } }) module.exports = app From 7628b4a6fe252370361096a03526d97d6b418d89 Mon Sep 17 00:00:00 2001 From: Leonardo Lodi Date: Tue, 18 Jun 2024 19:36:18 +0100 Subject: [PATCH 4/4] do mvc: add domain directory --- src/controllers/books/booksControllers.js | 111 ++++++++++++++ src/controllers/booksControllers.js | 173 ---------------------- src/controllers/films/filmsControllers.js | 116 +++++++++++++++ src/controllers/filmsControllers.js | 142 ------------------ src/controllers/users/usersControllers.js | 87 +++++++++++ src/controllers/usersControllers.js | 97 ------------ src/domain/books/booksRepository.js | 102 +++++++++++++ src/domain/films/filmsRepository.js | 80 ++++++++++ src/domain/users/usersRepository.js | 44 ++++++ src/errors/DataNotFound.js | 3 - src/errors/DataNotFoundError.js | 3 + src/routers/{ => books}/books.js | 2 +- src/routers/{ => films}/films.js | 2 +- src/routers/{ => users}/users.js | 2 +- src/server.js | 14 +- 15 files changed, 553 insertions(+), 425 deletions(-) create mode 100644 src/controllers/books/booksControllers.js delete mode 100644 src/controllers/booksControllers.js create mode 100644 src/controllers/films/filmsControllers.js delete mode 100644 src/controllers/filmsControllers.js create mode 100644 src/controllers/users/usersControllers.js delete mode 100644 src/controllers/usersControllers.js create mode 100644 src/domain/books/booksRepository.js create mode 100644 src/domain/films/filmsRepository.js create mode 100644 src/domain/users/usersRepository.js delete mode 100644 src/errors/DataNotFound.js create mode 100644 src/errors/DataNotFoundError.js rename src/routers/{ => books}/books.js (86%) rename src/routers/{ => films}/films.js (86%) rename src/routers/{ => users}/users.js (84%) diff --git a/src/controllers/books/booksControllers.js b/src/controllers/books/booksControllers.js new file mode 100644 index 0000000..18db6ec --- /dev/null +++ b/src/controllers/books/booksControllers.js @@ -0,0 +1,111 @@ +const { books } = require("../../../data/index.js") +const DataNotFoundError = require("../../errors/DataNotFoundError.js") +const { + verifyBookBody, + verifyBookTitle, + addBookToDb, + findBookId, + removeBookFromDb, + replaceBookInDb, + verifyPatchOfBookBody, + verifyBookBodyRequest, +} = require("../../domain/books/booksRepository.js") + +const getBooks = (req, res) => { + res.json({ + books: books, + }) +} + +const postBook = (req, res) => { + verifyBookBody(req) + + verifyBookTitle(req) + + const book = { id: books.length + 1, ...req.body } + + addBookToDb(book) + + res.status(201).json({ + book: book, + }) +} + +const getBookById = (req, res) => { + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + res.json({ + book: book, + }) +} + +const deleteBook = (req, res) => { + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + removeBookFromDb(book) + + res.json({ + book: book, + }) +} + +const updateBook = (req, res) => { + verifyBookBody(req) + + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + const updatedBook = { id: book.id, ...req.body } + + verifyBookTitle(req) + + replaceBookInDb(book, updatedBook) + + res.json({ + book: updatedBook, + }) +} + +const patchBook = (req, res) => { + verifyPatchOfBookBody(req) + + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + verifyBookTitle(req) + + let updatedBook = {} + + verifyBookBodyRequest(req, updatedBook, book) + + res.json({ + book: updatedBook, + }) +} + +module.exports = { + getBooks, + postBook, + getBookById, + deleteBook, + updateBook, + patchBook, +} diff --git a/src/controllers/booksControllers.js b/src/controllers/booksControllers.js deleted file mode 100644 index 8a8181a..0000000 --- a/src/controllers/booksControllers.js +++ /dev/null @@ -1,173 +0,0 @@ -const { books } = require("../../data") -const MissingDataError = require("../errors/MissingDataError") -const ExistingDataError = require("../errors/ExistingDataError") -const DataNotFound = require("../errors/DataNotFound") - -const getBooks = (req, res) => { - res.json({ - books: books, - }) -} - -const postBook = (req, res) => { - if (!req.body.title || !req.body.type || !req.body.author) { - throw new MissingDataError("Missing fields in request body") - } - - const existingBook = books.find((b) => b.title === req.body.title) - - if (existingBook) { - throw new ExistingDataError( - "A book with the provided title already exists" - ) - } - - const book = { id: books.length + 1, ...req.body } - - books.push(book) - - res.status(201).json({ - book: book, - }) -} - -const getBookById = (req, res) => { - const id = Number(req.params.id) - const book = books.find((b) => b.id === id) - - if (!book) { - throw new DataNotFound("A book the provided ID does not exist") - } - - res.json({ - book: book, - }) -} - -const deleteBook = (req, res) => { - const id = Number(req.params.id) - const book = books.find((b) => b.id === id) - - if (!book) { - throw new DataNotFound("A book the provided ID does not exist") - } - - books.splice(books.indexOf(book), 1) - - res.json({ - book: book, - }) -} - -const updateBook = (req, res) => { - if (!req.body.title || !req.body.type || !req.body.author) { - throw new MissingDataError("Missing fields in request body") - } - - const id = Number(req.params.id) - const book = books.find((b) => b.id === id) - - if (!book) { - throw new DataNotFound("A book the provided ID does not exist") - } - - const updatedBook = { id: book.id, ...req.body } - - const existingBook = books.find((b) => b.title === req.body.title) - - if (existingBook) { - throw new ExistingDataError( - "A book with the provided title already exists" - ) - } - - books.splice(books.indexOf(book), 1, updatedBook) - - res.json({ - book: updatedBook, - }) -} - -const patchBook = (req, res) => { - if (!req.body.title && !req.body.type && !req.body.author) { - throw new MissingDataError("Missing fields in request body") - } - - const id = Number(req.params.id) - const book = books.find((b) => b.id === id) - - if (!book) { - throw new DataNotFound("A book the provided ID does not exist") - } - - const existingBook = books.find((b) => b.title === req.body.title) - - if (existingBook) { - throw new ExistingDataError( - "A book with the provided title already exists" - ) - } - - let updatedBook = {} - - if (req.body.title && !req.body.type && !req.body.author) { - updatedBook = { - id: book.id, - ...req.body, - type: book.type, - author: book.author, - } - } - - if (req.body.title && req.body.type && !req.body.author) { - updatedBook = { id: book.id, ...req.body, author: book.author } - } - - if (req.body.title && !req.body.type && req.body.author) { - updatedBook = { - id: book.id, - title: req.body.title, - type: book.type, - author: req.body.author, - } - } - - if (!req.body.title && req.body.type && !req.body.author) { - updatedBook = { - id: book.id, - title: book.title, - ...req.body, - author: book.author, - } - } - - if (!req.body.title && req.body.type && req.body.author) { - updatedBook = { id: book.id, title: book.title, ...req.body } - } - - if (!req.body.title && !req.body.type && req.body.author) { - updatedBook = { - id: book.id, - title: book.title, - type: book.type, - ...req.body, - } - } - - if (req.body.title && req.body.type && req.body.author) { - updatedBook = { id: book.id, ...req.body } - } - - res.json({ - book: updatedBook, - }) -} - -module.exports = { - getBooks, - postBook, - getBookById, - deleteBook, - updateBook, - patchBook, -} diff --git a/src/controllers/films/filmsControllers.js b/src/controllers/films/filmsControllers.js new file mode 100644 index 0000000..fa18e57 --- /dev/null +++ b/src/controllers/films/filmsControllers.js @@ -0,0 +1,116 @@ +const { films } = require("../../../data/index.js") +const MissingDataError = require("../../errors/MissingDataError.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") +const DataNotFoundError = require("../../errors/DataNotFoundError.js") +const { + verifyFilmReqQuery, + verifyFilmBody, + verifyFilmTitle, + addFilmToDb, + findFilmById, + removeFilmFromDb, + replaceFilmInDb, + verifyFilmReqBody, + verifyMssingFields, +} = require("../../domain/films/filmsRepository.js") + +const getFilms = (req, res) => { + verifyFilmReqQuery(req, res) + + res.json({ + films: films, + }) +} + +const postFilm = (req, res) => { + verifyFilmBody(req) + + verifyFilmTitle(req) + + const film = { id: films.length + 1, ...req.body } + + addFilmToDb(film) + + res.status(201).json({ + film: film, + }) +} + +const getFilmById = (req, res) => { + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + res.json({ + film: film, + }) +} + +const deleteFilm = (req, res) => { + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + removeFilmFromDb(film) + + res.json({ + film: film, + }) +} + +const updateFilm = (req, res) => { + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + verifyFilmTitle(req) + + const updatedFilm = { id: film.id, ...req.body } + + replaceFilmInDb(film, updatedFilm) + + res.json({ + film: updatedFilm, + }) +} + +const patchFilm = (req, res) => { + verifyMssingFields(req) + + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + verifyFilmTitle(req) + + let updatedFilm = {} + + verifyFilmReqBody(req, updatedFilm, film) + + replaceFilmInDb(film, updatedFilm) + + res.json({ + film: updatedFilm, + }) +} + +module.exports = { + getFilms, + postFilm, + getFilmById, + deleteFilm, + updateFilm, + patchFilm, +} diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js deleted file mode 100644 index 0439ab3..0000000 --- a/src/controllers/filmsControllers.js +++ /dev/null @@ -1,142 +0,0 @@ -const { films } = require("../../data") -const MissingDataError = require("../errors/MissingDataError") -const ExistingDataError = require("../errors/ExistingDataError") -const DataNotFound = require("../errors/DataNotFound") - -const getFilms = (req, res) => { - if (req.query.director) { - const directorName = req.query.director.split(" ").join("").toLowerCase() - const directorFilms = films.filter( - (f) => f.director.split(" ").join("").toLowerCase() === directorName - ) - - return res.json({ - films: directorFilms, - }) - } - - res.json({ - films: films, - }) -} - -const postFilm = (req, res) => { - if (!req.body.title || !req.body.director) { - throw new MissingDataError("Missing fields in request body") - } - - const existingFilm = films.find((f) => f.title === req.body.title) - - if (existingFilm) { - throw new ExistingDataError( - "A film with the provided title already exists" - ) - } - - const film = { id: films.length + 1, ...req.body } - - films.push(film) - - res.status(201).json({ - film: film, - }) -} - -const getFilmById = (req, res) => { - const id = Number(req.params.id) - const film = films.find((f) => f.id === id) - - if (!film) { - throw new DataNotFound("A film with provided ID does not exist") - } - - res.json({ - film: film, - }) -} - -const deleteFilm = (req, res) => { - const id = Number(req.params.id) - const film = films.find((f) => f.id === id) - - if (!film) { - throw new DataNotFound("A film with provided ID does not exist") - } - - films.splice(films.indexOf(film), 1) - - res.json({ - film: film, - }) -} - -const updateFilm = (req, res) => { - const id = Number(req.params.id) - const film = films.find((f) => f.id === id) - - if (!film) { - throw new DataNotFound("A film with provided ID does not exist") - } - - const existingFilm = films.find((f) => f.title === req.body.title) - - if (existingFilm) { - throw new ExistingDataError( - "A film with the provided title already exists" - ) - } - - const updatedFilm = { id: film.id, ...req.body } - - films.splice(films.indexOf(film), 1, updatedFilm) - - res.json({ - film: updatedFilm, - }) -} - -const patchFilm = (req, res) => { - if (!req.body.title && !req.body.director) { - throw new MissingDataError("Missing fields in the request body") - } - - const id = Number(req.params.id) - const film = films.find((f) => f.id === id) - - if (!film) { - throw new DataNotFound("A film with provided ID does not exist") - } - - const existingFilm = films.find((f) => f.title === req.body.title) - - if (existingFilm) { - throw new ExistingDataError( - "A film with the provided title already exists" - ) - } - - let updatedFilm = {} - - if (!req.body.title && req.body.director) { - updatedFilm = { id: film.id, title: film.title, ...req.body } - } - - if (req.body.title && !req.body.director) { - updatedFilm = { id: film.id, ...req.body, director: film.director } - } - - films.splice(films.indexOf(film), 1, updatedFilm) - - res.json({ - film: updatedFilm, - }) -} - -module.exports = { - getFilms, - postFilm, - getFilmById, - deleteFilm, - updateFilm, - patchFilm, -} diff --git a/src/controllers/users/usersControllers.js b/src/controllers/users/usersControllers.js new file mode 100644 index 0000000..d7c37f2 --- /dev/null +++ b/src/controllers/users/usersControllers.js @@ -0,0 +1,87 @@ +const { users } = require("../../../data/index.js") +const { + verifyUserBody, + verifyUserEmail, + addUserToDb, + findUserId, + deleteUserFromDb, + replaceUserInDb, +} = require("../../domain/users/usersRepository.js") +const DataNotFoundError = require("../../errors/DataNotFoundError.js") + +const getUsers = (req, res) => { + res.json({ + users: users, + }) +} + +const postUser = (req, res) => { + verifyUserBody(req) + + verifyUserEmail(req) + + const user = { id: users.length + 1, ...req.body } + + addUserToDb(user) + + res.status(201).json({ + user: user, + }) +} + +const getUserById = (req, res) => { + const id = Number(req.params.id) + const user = findUserId(id) + + if (!user) { + throw new DataNotFoundError("A user with the provided ID does not exist") + } + + res.json({ + user: user, + }) +} + +const deleteUser = (req, res) => { + const id = Number(req.params.id) + const user = findUserId(id) + + if (!user) { + throw new DataNotFoundError("A user with the provided ID does not exist") + } + + deleteUserFromDb(user) + + res.json({ + user: user, + }) +} + +const updateUser = (req, res) => { + verifyUserBody(req) + + const id = Number(req.params.id) + const user = findUserId(id) + + if (!user) { + throw new DataNotFoundError("A user with the provided ID does not exist") + } + + verifyUserEmail(req) + + const updatedUser = { id: user.id, ...req.body } + + replaceUserInDb(user, updatedUser) + + res.json({ + user: updatedUser, + }) +} + +module.exports = { + getUsers, + postUser, + getUserById, + deleteUser, + updateUser, +} diff --git a/src/controllers/usersControllers.js b/src/controllers/usersControllers.js deleted file mode 100644 index ee30369..0000000 --- a/src/controllers/usersControllers.js +++ /dev/null @@ -1,97 +0,0 @@ -const { users } = require("../../data") -const MissingDataError = require("../errors/MissingDataError") -const ExistingDataError = require("../errors/ExistingDataError") -const DataNotFound = require("../errors/DataNotFound") - -const getUsers = (req, res) => { - res.json({ - users: users, - }) -} - -const postUser = (req, res) => { - if (!req.body.email) { - throw new MissingDataError("Missing fields in request body") - } - - const existingUser = users.find((u) => u.email === req.body.email) - - if (existingUser) { - throw new ExistingDataError( - "A user with the provided email already exists" - ) - } - - const user = { id: users.length + 1, ...req.body } - - users.push(user) - - res.status(201).json({ - user: user, - }) -} - -const getUserById = (req, res) => { - const id = Number(req.params.id) - const user = users.find((u) => u.id === id) - - if (!user) { - throw new DataNotFound("A user with the provided ID does not exist") - } - - res.json({ - user: user, - }) -} - -const deleteUser = (req, res) => { - const id = Number(req.params.id) - const user = users.find((u) => u.id === id) - - if (!user) { - throw new DataNotFound("A user with the provided ID does not exist") - } - - users.splice(users.indexOf(user), 1) - - res.json({ - user: user, - }) -} - -const updateUser = (req, res) => { - if (!req.body.email) { - throw new MissingDataError("Missing fields in request body") - } - - const id = Number(req.params.id) - const user = users.find((u) => u.id === id) - - if (!user) { - throw new DataNotFound("A user with the provided ID does not exist") - } - - const existingUser = users.find((u) => u.email === req.body.email) - - if (existingUser) { - throw new ExistingDataError( - "A user with the provided email already exists" - ) - } - - const updatedUser = { id: user.id, ...req.body } - - users.splice(users.indexOf(user), 1, updatedUser) - - res.json({ - user: updatedUser, - }) -} - -module.exports = { - getUsers, - postUser, - getUserById, - deleteUser, - updateUser, -} diff --git a/src/domain/books/booksRepository.js b/src/domain/books/booksRepository.js new file mode 100644 index 0000000..02484e1 --- /dev/null +++ b/src/domain/books/booksRepository.js @@ -0,0 +1,102 @@ +const { books } = require("../../../data/index.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") +const MissingDataError = require("../../errors/MissingDataError.js") + +const verifyBookBody = (req) => { + if (!req.body.title || !req.body.type || !req.body.author) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyBookTitle = (req) => { + const existingBook = books.find((b) => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError( + "A book with the provided title already exists" + ) + } +} + +const addBookToDb = (book) => { + books.push(book) +} + +const findBookId = (id) => { + return books.find((b) => b.id === id) +} + +const removeBookFromDb = (book) => { + books.splice(books.indexOf(book), 1) +} + +const replaceBookInDb = (book, updatedBook) => { + books.splice(books.indexOf(book), 1, updatedBook) +} + +const verifyPatchOfBookBody = (req) => { + if (!req.body.title && !req.body.type && !req.body.author) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyBookBodyRequest = (req, updatedBook, book) => { + if (req.body.title && !req.body.type && !req.body.author) { + return (updatedBook = { + id: book.id, + ...req.body, + type: book.type, + author: book.author, + }) + } + + if (req.body.title && req.body.type && !req.body.author) { + return (updatedBook = { id: book.id, ...req.body, author: book.author }) + } + + if (req.body.title && !req.body.type && req.body.author) { + return (updatedBook = { + id: book.id, + title: req.body.title, + type: book.type, + author: req.body.author, + }) + } + + if (!req.body.title && req.body.type && !req.body.author) { + return (updatedBook = { + id: book.id, + title: book.title, + ...req.body, + author: book.author, + }) + } + + if (!req.body.title && req.body.type && req.body.author) { + return (updatedBook = { id: book.id, title: book.title, ...req.body }) + } + + if (!req.body.title && !req.body.type && req.body.author) { + return (updatedBook = { + id: book.id, + title: book.title, + type: book.type, + ...req.body, + }) + } + + if (req.body.title && req.body.type && req.body.author) { + return (updatedBook = { id: book.id, ...req.body }) + } +} + +module.exports = { + verifyBookBody, + verifyBookTitle, + addBookToDb, + findBookId, + removeBookFromDb, + replaceBookInDb, + verifyPatchOfBookBody, + verifyBookBodyRequest, +} diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js new file mode 100644 index 0000000..a2f85aa --- /dev/null +++ b/src/domain/films/filmsRepository.js @@ -0,0 +1,80 @@ +const { films } = require("../../../data/index.js") +const MissingDataError = require("../../errors/MissingDataError.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") + +const verifyFilmReqQuery = (req, res) => { + if (req.query.director) { + const directorName = req.query.director.split(" ").join("").toLowerCase() + const directorFilms = films.filter( + (f) => f.director.split(" ").join("").toLowerCase() === directorName + ) + + return res.json({ + films: directorFilms, + }) + } +} + +const verifyFilmBody = (req) => { + if (!req.body.title || !req.body.director) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyFilmTitle = (req) => { + const existingFilm = films.find((f) => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError( + "A film with the provided title already exists" + ) + } +} + +const addFilmToDb = (film) => { + films.push(film) +} + +const findFilmById = (id) => { + return films.find((f) => f.id === id) +} + +const removeFilmFromDb = (film) => { + films.splice(films.indexOf(film), 1) +} + +const replaceFilmInDb = (film, updatedFilm) => { + films.splice(films.indexOf(film), 1, updatedFilm) +} + +const verifyFilmReqBody = (req, updatedFilm, film) => { + if (!req.body.title && req.body.director) { + return (updatedFilm = { id: film.id, title: film.title, ...req.body }) + } + + if (req.body.title && !req.body.director) { + return (updatedFilm = { + id: film.id, + ...req.body, + director: film.director, + }) + } +} + +const verifyMssingFields = (req) => { + if (!req.body.title && !req.body.director) { + throw new MissingDataError("Missing fields in request body") + } +} + +module.exports = { + verifyFilmReqQuery, + verifyFilmBody, + verifyFilmTitle, + addFilmToDb, + findFilmById, + removeFilmFromDb, + replaceFilmInDb, + verifyFilmReqBody, + verifyMssingFields, +} diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js new file mode 100644 index 0000000..216cce6 --- /dev/null +++ b/src/domain/users/usersRepository.js @@ -0,0 +1,44 @@ +const { users } = require("../../../data/index.js") +const MissingDataError = require("../../errors/MissingDataError.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") + +const verifyUserBody = (req) => { + if (!req.body.email) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyUserEmail = (req) => { + const existingUser = users.find((u) => u.email === req.body.email) + + if (existingUser) { + throw new ExistingDataError( + "A user with the provided email already exists" + ) + } +} + +const addUserToDb = (user) => { + users.push(user) +} + +const findUserId = (id) => { + return users.find((u) => u.id === id) +} + +const deleteUserFromDb = (user) => { + users.splice(users.indexOf(user), 1) +} + +const replaceUserInDb = (user, updatedUser) => { + users.splice(users.indexOf(user), 1, updatedUser) +} + +module.exports = { + verifyUserBody, + verifyUserEmail, + addUserToDb, + findUserId, + deleteUserFromDb, + replaceUserInDb, +} diff --git a/src/errors/DataNotFound.js b/src/errors/DataNotFound.js deleted file mode 100644 index f4ac51d..0000000 --- a/src/errors/DataNotFound.js +++ /dev/null @@ -1,3 +0,0 @@ -class DataNotFound extends Error {} - -module.exports = DataNotFound diff --git a/src/errors/DataNotFoundError.js b/src/errors/DataNotFoundError.js new file mode 100644 index 0000000..a4a42d7 --- /dev/null +++ b/src/errors/DataNotFoundError.js @@ -0,0 +1,3 @@ +class DataNotFoundError extends Error {} + +module.exports = DataNotFoundError diff --git a/src/routers/books.js b/src/routers/books/books.js similarity index 86% rename from src/routers/books.js rename to src/routers/books/books.js index 47e5d44..05f7ef3 100644 --- a/src/routers/books.js +++ b/src/routers/books/books.js @@ -6,7 +6,7 @@ const { updateBook, patchBook, getBooks, -} = require("../controllers/booksControllers") +} = require("../../controllers/books/booksControllers.js") const router = express.Router() router.get("/", getBooks) diff --git a/src/routers/films.js b/src/routers/films/films.js similarity index 86% rename from src/routers/films.js rename to src/routers/films/films.js index ef297a1..74f100e 100644 --- a/src/routers/films.js +++ b/src/routers/films/films.js @@ -6,7 +6,7 @@ const { deleteFilm, updateFilm, patchFilm, -} = require("../controllers/filmsControllers") +} = require("../../controllers/films/filmsControllers.js") const router = express.Router() router.get("/", getFilms) diff --git a/src/routers/users.js b/src/routers/users/users.js similarity index 84% rename from src/routers/users.js rename to src/routers/users/users.js index 886d1f4..9f8050e 100644 --- a/src/routers/users.js +++ b/src/routers/users/users.js @@ -5,7 +5,7 @@ const { getUserById, deleteUser, updateUser, -} = require("../controllers/usersControllers") +} = require("../../controllers/users/usersControllers.js") const router = express.Router() router.get("/", getUsers) diff --git a/src/server.js b/src/server.js index ff5fa94..97f3946 100644 --- a/src/server.js +++ b/src/server.js @@ -10,9 +10,9 @@ app.use(express.json()) app.use(morgan("dev")) // REQUIRE ROUTERS -const usersRouter = require("./routers/users") -const filmsRouter = require("./routers/films") -const booksRouter = require("./routers/books") +const usersRouter = require("./routers/users/users.js") +const filmsRouter = require("./routers/films/films.js") +const booksRouter = require("./routers/books/books.js") // ADD ROUTERS TO APP app.use("/users", usersRouter) @@ -20,9 +20,9 @@ app.use("/films", filmsRouter) app.use("/books", booksRouter) // ADD ERRORS CLASSES -const MissingDataError = require("./errors/MissingDataError") -const ExistingDataError = require("./errors/ExistingDataError") -const DataNotFound = require("./errors/DataNotFound") +const MissingDataError = require("./errors/MissingDataError.js") +const ExistingDataError = require("./errors/ExistingDataError.js") +const DataNotFoundError = require("./errors/DataNotFoundError.js") app.use((error, req, res, next) => { if (error instanceof MissingDataError) { @@ -37,7 +37,7 @@ app.use((error, req, res, next) => { }) } - if (error instanceof DataNotFound) { + if (error instanceof DataNotFoundError) { return res.status(404).json({ error: error.message, })