From b466109e0c76dd10883b17c6a551fd78f112c0b8 Mon Sep 17 00:00:00 2001 From: Thomas Jensen Date: Tue, 6 Aug 2024 11:37:34 +0100 Subject: [PATCH 1/3] Completed core --- package-lock.json | 73 +++++------------ src/routers/books.js | 112 +++++++++++++++++++++++++- src/routers/pets.js | 117 +++++++++++++++++++++++++++ src/server.js | 16 ++-- test/api/routes/books.spec.js | 147 +++++++++++++++++----------------- 5 files changed, 330 insertions(+), 135 deletions(-) create mode 100644 src/routers/pets.js diff --git a/package-lock.json b/package-lock.json index 37ccdff8..717f0215 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1441,12 +1441,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1740,9 +1741,10 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2024,16 +2026,17 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -2064,43 +2067,6 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/faker": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", @@ -2128,10 +2094,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2587,6 +2554,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -4805,6 +4773,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, diff --git a/src/routers/books.js b/src/routers/books.js index 1551dd87..977f1099 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,9 +1,117 @@ const express = require('express') const router = express.Router() -const db = require("../../db"); +const db = require('../../db') -router.get('/', async (req, res) => { +router.post('/', async (req, res, next) => { + const { title, type, author, topic, publication_date, pages } = req.body + try { + await db.query( + ` + INSERT INTO books (title, type, author, topic, publication_date, pages) + VALUES ($1, $2, $3, $4, $5, $6) + `, + [title, type, author, topic, publication_date, pages] + ) + + const response = await db.query( + ` + SELECT * FROM books WHERE title = $1 + `, + [title] + ) + const [book] = response.rows + + res.status(201).json({ book: book }) + } catch (err) { + next(new Error('Could not add book: ', err)) + } +}) + +router.get('/', async (req, res, next) => { + try { + const response = await db.query(` + SELECT * FROM books + `) + + const books = response.rows + + res.json({ books: books }) + } catch (err) { + next(new Error('Could not get books: ', err)) + } +}) + +router.get('/:id', async (req, res, next) => { + const id = parseInt(req.params.id) + + try { + const response = await db.query( + ` + SELECT * FROM books WHERE id = $1 + `, + [id] + ) + + const [book] = response.rows + + res.json({ book: book }) + } catch (err) { + next(new Error(`Could not get book with id ${id}:`, err)) + } +}) + +router.put('/:id', async (req, res, next) => { + const id = parseInt(req.params.id) + const { title, type, author, topic, publication_date, pages } = req.body + + try { + await db.query( + ` + UPDATE books + SET title = $1, type = $2, author = $3, topic = $4, publication_date = $5, pages = $6 + WHERE id = $7 + `, + [title, type, author, topic, publication_date, pages, id] + ) + + const response = await db.query( + ` + SELECT * FROM books WHERE id = $1 + `, + [id] + ) + const [book] = response.rows + + res.status(201).json({ book }) + } catch (err) { + next(new Error(`Could not update book with id ${id}: `, err)) + } +}) + +router.delete('/:id', async (req, res, next) => { + const id = parseInt(req.params.id) + + try { + const deletedBook = await db.query( + ` + SELECT * FROM books WHERE id = $1 + `, + [id] + ) + const [book] = deletedBook.rows + + await db.query( + ` + DELETE FROM books WHERE id = $1 + `, + [id] + ) + + res.status(201).json({ book: book }) + } catch (err) { + next(new Error(`Could not delete book with id ${id}:`, err)) + } }) module.exports = router diff --git a/src/routers/pets.js b/src/routers/pets.js new file mode 100644 index 00000000..fe2d38d7 --- /dev/null +++ b/src/routers/pets.js @@ -0,0 +1,117 @@ +const express = require('express') +const router = express.Router() +const db = require('../../db') + +router.post('/', async (req, res, next) => { + const { name, age, type, breed, has_microchip } = req.body + + try { + await db.query( + ` + INSERT INTO pets (name, age, type, breed, has_microchip) + VALUES ($1, $2, $3, $4, $5) + `, + [name, age, type, breed, has_microchip] + ) + + const response = await db.query( + ` + SELECT * FROM pets WHERE name = $1 + `, + [name] + ) + const [pet] = response.rows + + res.status(201).json({ pet: pet }) + } catch (err) { + next(new Error('Could not add pet: ', err)) + } +}) + +router.get('/', async (req, res, next) => { + try { + const response = await db.query(` + SELECT * FROM pets + `) + + const pets = response.rows + + res.json({ pets: pets }) + } catch (err) { + next(new Error('Could not get pets: ', err)) + } +}) + +router.get('/:id', async (req, res, next) => { + const id = parseInt(req.params.id) + + try { + const response = await db.query( + ` + SELECT * FROM pets WHERE id = $1 + `, + [id] + ) + + const [pet] = response.rows + + res.json({ pet: pet }) + } catch (err) { + next(new Error(`Could not get pet with id ${id}:`, err)) + } +}) + +router.put('/:id', async (req, res, next) => { + const id = parseInt(req.params.id) + const { name, age, type, breed, has_microchip } = req.body + + try { + await db.query( + ` + UPDATE pets + SET name = $1, age = $2, type = $3, breed = $4, has_microchip = $5 + WHERE id = $6 + `, + [name, age, type, breed, has_microchip, id] + ) + + const response = await db.query( + ` + SELECT * FROM pets WHERE id = $1 + `, + [id] + ) + const [pet] = response.rows + + res.status(201).json({ pet }) + } catch (err) { + next(new Error(`Could not update pet with id ${id}: `, err)) + } +}) + +router.delete('/:id', async (req, res, next) => { + const id = parseInt(req.params.id) + + try { + const deletedPet = await db.query( + ` + SELECT * FROM pets WHERE id = $1 + `, + [id] + ) + const [pet] = deletedPet.rows + + await db.query( + ` + DELETE FROM pets WHERE id = $1 + `, + [id] + ) + + res.status(201).json({ pet: pet }) + } catch (err) { + next(new Error(`Could not delete pet with id ${id}:`, err)) + } +}) + +module.exports = router diff --git a/src/server.js b/src/server.js index dac55e5d..002ebced 100644 --- a/src/server.js +++ b/src/server.js @@ -1,16 +1,18 @@ -const express = require("express"); -const morgan = require("morgan"); -const cors = require("cors"); +const express = require('express') +const morgan = require('morgan') +const cors = require('cors') -const app = express(); +const app = express() -app.use(morgan("dev")); -app.use(cors()); -app.use(express.json()); +app.use(morgan('dev')) +app.use(cors()) +app.use(express.json()) //TODO: Implement books and pets APIs using Express Modular Routers const booksRouter = require('./routers/books.js') +const petsRouter = require('./routers/pets.js') app.use('/books', booksRouter) +app.use('/pets', petsRouter) module.exports = app diff --git a/test/api/routes/books.spec.js b/test/api/routes/books.spec.js index 833f599d..21addaf3 100644 --- a/test/api/routes/books.spec.js +++ b/test/api/routes/books.spec.js @@ -1,88 +1,87 @@ -const supertest = require("supertest") -const app = require("../../../src/server.js") -const { book1, book2 } = require("../../fixtures/bookData.js") -const createBook = require("../../helpers/createBook.js") - -describe("Books Endpoint", () => { - describe("POST /books", () => { - - it("will create a new book", async () => { - const response = await supertest(app).post("/books").send(book1) - - expect(response.status).toEqual(201) - expect(response.body.book).not.toEqual(undefined) - expect(response.body.book.id).not.toEqual(undefined) - - for (prop in book1) { - expect(response.body.book[prop]).toEqual(book1[prop]) - } +const supertest = require('supertest') +const app = require('../../../src/server.js') +const { book1, book2 } = require('../../fixtures/bookData.js') +const createBook = require('../../helpers/createBook.js') + +describe('Books Endpoint', () => { + describe('POST /books', () => { + it('will create a new book', async () => { + const response = await supertest(app).post('/books').send(book1) + + expect(response.status).toEqual(201) + expect(response.body.book).not.toEqual(undefined) + expect(response.body.book.id).not.toEqual(undefined) + + for (prop in book1) { + expect(response.body.book[prop]).toEqual(book1[prop]) + } + }) }) - }) - describe("GET /books", () => { - beforeEach(async () => { - await createBook(Object.values(book1)) - await createBook(Object.values(book2)) + describe('GET /books', () => { + beforeEach(async () => { + await createBook(Object.values(book1)) + await createBook(Object.values(book2)) + }) + + it('will list all books', async () => { + const response = await supertest(app).get('/books') + + expect(response.status).toEqual(200) + expect(response.body.books).not.toEqual(undefined) + expect(response.body.books.length).toEqual(2) + const expectedBooks = [book1, book2] + response.body.books.forEach((retrievedBook, index) => { + expect(retrievedBook.title).toEqual(expectedBooks[index].title) + }) + }) + + it('will list a book', async () => { + const response = await supertest(app).get('/books/1') + + expect(response.status).toEqual(200) + expect(response.body.book).not.toEqual(undefined) + expect(response.body.book.id).not.toEqual(undefined) + + for (prop in book1) { + expect(response.body.book[prop]).toEqual(book1[prop]) + } + }) }) - it("will list all books", async () => { - const response = await supertest(app).get("/books") + describe('PUT /books', () => { + beforeEach(async () => { + await createBook(Object.values(book1)) + }) - expect(response.status).toEqual(200) - expect(response.body.books).not.toEqual(undefined) - expect(response.body.books.length).toEqual(2) - const expectedBooks = [book1, book2] - response.body.books.forEach((retrievedBook, index) => { - expect(retrievedBook.title).toEqual(expectedBooks[index].title) - }) - }) - - it("will list a book", async () => { - const response = await supertest(app).get("/books/1") + it('will update a books', async () => { + const response = await supertest(app).put('/books/1').send(book2) - expect(response.status).toEqual(200) - expect(response.body.book).not.toEqual(undefined) - expect(response.body.book.id).not.toEqual(undefined) + expect(response.status).toEqual(201) + expect(response.body.book).not.toEqual(undefined) + expect(response.body.book.id).not.toEqual(undefined) - for (prop in book1) { - expect(response.body.book[prop]).toEqual(book1[prop]) - } + for (prop in book2) { + expect(response.body.book[prop]).toEqual(book2[prop]) + } + }) }) - }) - describe("PUT /books", () => { - beforeEach(async () => { - await createBook(Object.values(book1)) - }) - - it("will update a books", async () => { - const response = await supertest(app).put("/books/1").send(book2) - - expect(response.status).toEqual(201) - expect(response.body.book).not.toEqual(undefined) - expect(response.body.book.id).not.toEqual(undefined) - - for (prop in book2) { - expect(response.body.book[prop]).toEqual(book2[prop]) - } - }) - }) - - describe("DELETE /books", () => { - beforeEach(async () => { - await createBook(Object.values(book1)) - }) + describe('DELETE /books', () => { + beforeEach(async () => { + await createBook(Object.values(book1)) + }) - it("will return the deleted the book", async () => { - const response = await supertest(app).delete("/books/1") + it('will return the deleted the book', async () => { + const response = await supertest(app).delete('/books/1') - expect(response.status).toEqual(201) - expect(response.body.book).not.toEqual(undefined) - expect(response.body.book.id).not.toEqual(undefined) + expect(response.status).toEqual(201) + expect(response.body.book).not.toEqual(undefined) + expect(response.body.book.id).not.toEqual(undefined) - for (prop in book1) { - expect(response.body.book[prop]).toEqual(book1[prop]) - } + for (prop in book1) { + expect(response.body.book[prop]).toEqual(book1[prop]) + } + }) }) - }) }) From d9488c938ac320da8a19f4e857edfa5c10aa776b Mon Sep 17 00:00:00 2001 From: Thomas Jensen Date: Tue, 6 Aug 2024 11:43:00 +0100 Subject: [PATCH 2/3] Optimised code because I don't know SQL --- src/routers/books.js | 32 +++++++------------------------- src/routers/pets.js | 32 +++++++------------------------- 2 files changed, 14 insertions(+), 50 deletions(-) diff --git a/src/routers/books.js b/src/routers/books.js index 977f1099..ffe06de5 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -6,20 +6,14 @@ router.post('/', async (req, res, next) => { const { title, type, author, topic, publication_date, pages } = req.body try { - await db.query( + const response = await db.query( ` INSERT INTO books (title, type, author, topic, publication_date, pages) VALUES ($1, $2, $3, $4, $5, $6) + returning * `, [title, type, author, topic, publication_date, pages] ) - - const response = await db.query( - ` - SELECT * FROM books WHERE title = $1 - `, - [title] - ) const [book] = response.rows res.status(201).json({ book: book }) @@ -66,21 +60,15 @@ router.put('/:id', async (req, res, next) => { const { title, type, author, topic, publication_date, pages } = req.body try { - await db.query( + const response = await db.query( ` UPDATE books SET title = $1, type = $2, author = $3, topic = $4, publication_date = $5, pages = $6 WHERE id = $7 + returning * `, [title, type, author, topic, publication_date, pages, id] ) - - const response = await db.query( - ` - SELECT * FROM books WHERE id = $1 - `, - [id] - ) const [book] = response.rows res.status(201).json({ book }) @@ -93,20 +81,14 @@ router.delete('/:id', async (req, res, next) => { const id = parseInt(req.params.id) try { - const deletedBook = await db.query( - ` - SELECT * FROM books WHERE id = $1 - `, - [id] - ) - const [book] = deletedBook.rows - - await db.query( + const response = await db.query( ` DELETE FROM books WHERE id = $1 + returning * `, [id] ) + const [book] = response.rows res.status(201).json({ book: book }) } catch (err) { diff --git a/src/routers/pets.js b/src/routers/pets.js index fe2d38d7..8acfd3ca 100644 --- a/src/routers/pets.js +++ b/src/routers/pets.js @@ -6,20 +6,14 @@ router.post('/', async (req, res, next) => { const { name, age, type, breed, has_microchip } = req.body try { - await db.query( + const response = await db.query( ` INSERT INTO pets (name, age, type, breed, has_microchip) VALUES ($1, $2, $3, $4, $5) + returning * `, [name, age, type, breed, has_microchip] ) - - const response = await db.query( - ` - SELECT * FROM pets WHERE name = $1 - `, - [name] - ) const [pet] = response.rows res.status(201).json({ pet: pet }) @@ -66,21 +60,15 @@ router.put('/:id', async (req, res, next) => { const { name, age, type, breed, has_microchip } = req.body try { - await db.query( + const response = await db.query( ` UPDATE pets SET name = $1, age = $2, type = $3, breed = $4, has_microchip = $5 WHERE id = $6 + returning * `, [name, age, type, breed, has_microchip, id] ) - - const response = await db.query( - ` - SELECT * FROM pets WHERE id = $1 - `, - [id] - ) const [pet] = response.rows res.status(201).json({ pet }) @@ -93,20 +81,14 @@ router.delete('/:id', async (req, res, next) => { const id = parseInt(req.params.id) try { - const deletedPet = await db.query( - ` - SELECT * FROM pets WHERE id = $1 - `, - [id] - ) - const [pet] = deletedPet.rows - - await db.query( + const response = await db.query( ` DELETE FROM pets WHERE id = $1 + returning * `, [id] ) + const [pet] = response.rows res.status(201).json({ pet: pet }) } catch (err) { From e220b9450eaf3669be6642f76ee588f06156f54d Mon Sep 17 00:00:00 2001 From: Thomas Jensen Date: Tue, 6 Aug 2024 12:41:43 +0100 Subject: [PATCH 3/3] Completed Extension 2 --- src/routers/base.controller.js | 71 +++++++++++++++++++++++ src/routers/books.controller.js | 50 ++++++++++++++++ src/routers/books.js | 100 +++----------------------------- src/routers/pets.controller.js | 52 +++++++++++++++++ src/routers/pets.js | 100 +++----------------------------- 5 files changed, 187 insertions(+), 186 deletions(-) create mode 100644 src/routers/base.controller.js create mode 100644 src/routers/books.controller.js create mode 100644 src/routers/pets.controller.js diff --git a/src/routers/base.controller.js b/src/routers/base.controller.js new file mode 100644 index 00000000..205b5719 --- /dev/null +++ b/src/routers/base.controller.js @@ -0,0 +1,71 @@ +const db = require('../../db') + +class BaseController { + constructor(tableName) { + this.tableName = tableName + } + + async getAll(req, res, next) { + try { + const response = await db.query( + ` + SELECT * FROM ${this.tableName} + ` + ) + const items = response.rows + + res.json({ [this.tableName]: items }) + } catch (err) { + next(new Error(`Could not get ${this.tableName}: `, err)) + } + } + + async getById(req, res, next) { + const id = parseInt(req.params.id) + + try { + const response = await db.query( + ` + SELECT * FROM ${this.tableName} WHERE id = $1 + `, + [id] + ) + const [item] = response.rows + + res.json({ [this.tableName.slice(0, -1)]: item }) + } catch (err) { + next( + new Error( + `Could not get item from ${this.tableName} with id ${id}:`, + err + ) + ) + } + } + + async delete(req, res, next) { + const id = parseInt(req.params.id) + + try { + const response = await db.query( + ` + DELETE FROM ${this.tableName} WHERE id = $1 + returning * + `, + [id] + ) + const [item] = response.rows + + res.status(201).json({ [this.tableName.slice(0, -1)]: item }) + } catch (err) { + next( + new Error( + `Could not delete ${this.tableName} with id ${id}:`, + err + ) + ) + } + } +} + +module.exports = BaseController diff --git a/src/routers/books.controller.js b/src/routers/books.controller.js new file mode 100644 index 00000000..841d67b1 --- /dev/null +++ b/src/routers/books.controller.js @@ -0,0 +1,50 @@ +const db = require('../../db') +const BaseController = require('./base.controller') + +class BooksController extends BaseController { + constructor() { + super('books') + } + + async addBook(req, res, next) { + const { title, type, author, topic, publication_date, pages } = req.body + + try { + const response = await db.query( + ` + INSERT INTO books (title, type, author, topic, publication_date, pages) + VALUES ($1, $2, $3, $4, $5, $6) + returning * + `, + [title, type, author, topic, publication_date, pages] + ) + const [book] = response.rows + + res.status(201).json({ book: book }) + } catch (err) { + next(new Error('Could not add book: ', err)) + } + } + + async updateBook(req, res, next) { + const { title, type, author, topic, publication_date, pages } = req.body + + try { + const response = await db.query( + ` + INSERT INTO books (title, type, author, topic, publication_date, pages) + VALUES ($1, $2, $3, $4, $5, $6) + returning * + `, + [title, type, author, topic, publication_date, pages] + ) + const [book] = response.rows + + res.status(201).json({ book: book }) + } catch (err) { + next(new Error('Could not add book: ', err)) + } + } +} + +module.exports = BooksController diff --git a/src/routers/books.js b/src/routers/books.js index ffe06de5..2a30757a 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,99 +1,13 @@ const express = require('express') const router = express.Router() -const db = require('../../db') -router.post('/', async (req, res, next) => { - const { title, type, author, topic, publication_date, pages } = req.body +const BooksController = require('./books.controller') +const booksController = new BooksController() - try { - const response = await db.query( - ` - INSERT INTO books (title, type, author, topic, publication_date, pages) - VALUES ($1, $2, $3, $4, $5, $6) - returning * - `, - [title, type, author, topic, publication_date, pages] - ) - const [book] = response.rows - - res.status(201).json({ book: book }) - } catch (err) { - next(new Error('Could not add book: ', err)) - } -}) - -router.get('/', async (req, res, next) => { - try { - const response = await db.query(` - SELECT * FROM books - `) - - const books = response.rows - - res.json({ books: books }) - } catch (err) { - next(new Error('Could not get books: ', err)) - } -}) - -router.get('/:id', async (req, res, next) => { - const id = parseInt(req.params.id) - - try { - const response = await db.query( - ` - SELECT * FROM books WHERE id = $1 - `, - [id] - ) - - const [book] = response.rows - - res.json({ book: book }) - } catch (err) { - next(new Error(`Could not get book with id ${id}:`, err)) - } -}) - -router.put('/:id', async (req, res, next) => { - const id = parseInt(req.params.id) - const { title, type, author, topic, publication_date, pages } = req.body - - try { - const response = await db.query( - ` - UPDATE books - SET title = $1, type = $2, author = $3, topic = $4, publication_date = $5, pages = $6 - WHERE id = $7 - returning * - `, - [title, type, author, topic, publication_date, pages, id] - ) - const [book] = response.rows - - res.status(201).json({ book }) - } catch (err) { - next(new Error(`Could not update book with id ${id}: `, err)) - } -}) - -router.delete('/:id', async (req, res, next) => { - const id = parseInt(req.params.id) - - try { - const response = await db.query( - ` - DELETE FROM books WHERE id = $1 - returning * - `, - [id] - ) - const [book] = response.rows - - res.status(201).json({ book: book }) - } catch (err) { - next(new Error(`Could not delete book with id ${id}:`, err)) - } -}) +router.post('/', booksController.addBook.bind(booksController)) +router.get('/', booksController.getAll.bind(booksController)) +router.get('/:id', booksController.getById.bind(booksController)) +router.put('/:id', booksController.updateBook.bind(booksController)) +router.delete('/:id', booksController.delete.bind(booksController)) module.exports = router diff --git a/src/routers/pets.controller.js b/src/routers/pets.controller.js new file mode 100644 index 00000000..ac571c53 --- /dev/null +++ b/src/routers/pets.controller.js @@ -0,0 +1,52 @@ +const db = require('../../db') +const BaseController = require('./base.controller') + +class PetsController extends BaseController { + constructor() { + super('pets') + } + + async addPet(req, res, next) { + const { name, age, type, breed, has_microchip } = req.body + + try { + const response = await db.query( + ` + INSERT INTO pets (name, age, type, breed, has_microchip) + VALUES ($1, $2, $3, $4, $5) + returning * + `, + [name, age, type, breed, has_microchip] + ) + const [pet] = response.rows + + res.status(201).json({ pet: pet }) + } catch (err) { + next(new Error('Could not add pet: ', err)) + } + } + + async updatePet(req, res, next) { + const id = parseInt(req.params.id) + const { name, age, type, breed, has_microchip } = req.body + + try { + const response = await db.query( + ` + UPDATE pets + SET name = $1, age = $2, type = $3, breed = $4, has_microchip = $5 + WHERE id = $6 + returning * + `, + [name, age, type, breed, has_microchip, id] + ) + const [pet] = response.rows + + res.status(201).json({ pet }) + } catch (err) { + next(new Error(`Could not update pet with id ${id}: `, err)) + } + } +} + +module.exports = PetsController diff --git a/src/routers/pets.js b/src/routers/pets.js index 8acfd3ca..a637ca55 100644 --- a/src/routers/pets.js +++ b/src/routers/pets.js @@ -1,99 +1,13 @@ const express = require('express') const router = express.Router() -const db = require('../../db') -router.post('/', async (req, res, next) => { - const { name, age, type, breed, has_microchip } = req.body +const PetsController = require('./pets.controller') +const petsController = new PetsController() - try { - const response = await db.query( - ` - INSERT INTO pets (name, age, type, breed, has_microchip) - VALUES ($1, $2, $3, $4, $5) - returning * - `, - [name, age, type, breed, has_microchip] - ) - const [pet] = response.rows - - res.status(201).json({ pet: pet }) - } catch (err) { - next(new Error('Could not add pet: ', err)) - } -}) - -router.get('/', async (req, res, next) => { - try { - const response = await db.query(` - SELECT * FROM pets - `) - - const pets = response.rows - - res.json({ pets: pets }) - } catch (err) { - next(new Error('Could not get pets: ', err)) - } -}) - -router.get('/:id', async (req, res, next) => { - const id = parseInt(req.params.id) - - try { - const response = await db.query( - ` - SELECT * FROM pets WHERE id = $1 - `, - [id] - ) - - const [pet] = response.rows - - res.json({ pet: pet }) - } catch (err) { - next(new Error(`Could not get pet with id ${id}:`, err)) - } -}) - -router.put('/:id', async (req, res, next) => { - const id = parseInt(req.params.id) - const { name, age, type, breed, has_microchip } = req.body - - try { - const response = await db.query( - ` - UPDATE pets - SET name = $1, age = $2, type = $3, breed = $4, has_microchip = $5 - WHERE id = $6 - returning * - `, - [name, age, type, breed, has_microchip, id] - ) - const [pet] = response.rows - - res.status(201).json({ pet }) - } catch (err) { - next(new Error(`Could not update pet with id ${id}: `, err)) - } -}) - -router.delete('/:id', async (req, res, next) => { - const id = parseInt(req.params.id) - - try { - const response = await db.query( - ` - DELETE FROM pets WHERE id = $1 - returning * - `, - [id] - ) - const [pet] = response.rows - - res.status(201).json({ pet: pet }) - } catch (err) { - next(new Error(`Could not delete pet with id ${id}:`, err)) - } -}) +router.post('/', petsController.addPet.bind(petsController)) +router.get('/', petsController.getAll.bind(petsController)) +router.get('/:id', petsController.getById.bind(petsController)) +router.put('/:id', petsController.updatePet.bind(petsController)) +router.delete('/:id', petsController.delete.bind(petsController)) module.exports = router