Retrieving A Book By ID - Implementation

1 - Route Name

We will first add a route of GET /api/v1/books/:id.

File: src/routes/book.route.js

const express = require('express')
const router = express.Router()

const {
  getAllBooks,
  getBookById
} = require('../controllers/book')

router.get('/', getAllBooks)
router.get('/:id', getBookById) // This is our newly added route

module.exports = router

Followed by the controller setup.

File: src/controllers/books/getABookById.js

const catchException = require('../utils/catchExceptions')

const getBookById = catchException(async (req, res, next) => {
  // our code goes here...
})

2 - Input Request

None.

3 - Middleware

None.

4 - Validation

None.

5 - Domain

The getById() method will look this, nice and simple.

File: src/domain/services/bookRepository.js

// Retrieve - one
const getById = async (id) => {
  return await Model.findById(id)
}

Now for us to actually use the bookRepository in our bookService.

File: src/domain/services/bookService.js

// Retrieve - one
const getBookById = async (bookId) => {
  const book = await bookRepository.getById(bookId)

  return book
}

6 - Events

None.

7 - Response

But wait! let's not forget the 404 validation we promised.

File: src/domain/services/bookService.js

// Retrieve - one
const getBookById = async (bookId) => {
  if (!mongoose.Types.ObjectId.isValid(bookId)) {
    // the id is invalid
    throw new ApiException({
      message: `the book with that id: ${bookId} does not exist.`,
      status: 'failed',
      code: 404,
      data: null,
      errors: [`the book with that id: ${bookId} does not exist.`]
    })
  }

  const book = await bookRepository.getById(bookId)

  if (!book) {
    throw new ApiException({
      message: `the book with that id: ${bookId} does not exist.`,
      status: 'failed',
      code: 404,
      data: null,
      errors: [`the book with that id: ${bookId} does not exist.`]
    })
  }

  return book
}

As usual, here is our controller. Thanks to us doing the business logic validation in our domain layer, our controller is thin and free of clutter.

File: src/controllers/book.controller.js

const getBookById = catchException(async (req, res, next) => {
  const book = await bookService.getBookById(req.params.id)

  return res.json(
    globalResponseDTO({
      status: 'success',
      code: 200,
      message: `Book with the specified id.`,
      data: book,
      errors: null
    })
  )
})

Last updated