# Deleting A Book Listing By ID - Implementation

## 1 - Route Name

This will be our final API endpoint!

`DELETE /api/v1/books/:id`

Just like we planned, let's add in the route and our controller.

*File: src/routes/book.route.js*

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

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

router.get('/', getAllBooks)
router.get('/:id', getBookById)
router.post('/', createABook)
router.put('/:id', updateABook)

// This is the new route we are adding in
router.delete('/:id', deleteABook)
```

*File: src/controllers/book/deleteABook.js*

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

/**
 * Deletes an existing new book listing.
 */
const deleteABook = catchException(async (req, res) => {
  // Our code goes here
})
```

## 2 - Input Request

None.

## 3 - Middleware

As mentioned before, we will be reusing our `isAuthenticated` and `bookPermission` middleware.

If we plug those in, our route should look something like this.

*File: src/routes/book.route.js*

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

const { deleteABook } = require('../controllers/book')

const isAuthenticated = require('../middleware/auth.middleware')
const bookPermission = require('../middleware/bookPermission.middleware')

router.delete('/:id', isAuthenticated, bookPermission, deleteABook)

module.exports = router
```

## 4 - Validation

None.

## 5 - Domain

If you've followed along till this point, then the following will be of no surprise to you. Do note that because we are deleting a book, the `deleteOne` method from mongoose will either return a 1 for successful deletion or a 0 for a failed deletion. For a failed deletion to happen, it will have been an invalid `bookId` was inputted. Recall that we have already taken care of that in our `bookPermission` middleware, so no error handling is necessary here.

*File: src/domain/repositories/book.repository.js*

```javascript
const Model = require('../models/book.model')

// Delete
const deleteById = async (id) => {
  return await Model.deleteOne({ _id: id })
}

module.exports = {
  deleteById
}
```

*File: src/domain/services/book.service.js*

```javascript
const mongoose = require('mongoose')
const ApiException = require('../../utils/ApiException')
const bookRepository = require('../repositories/book.repository')
const checkBookId = require('../../utils/checkBookId')

// Delete a book
const deleteBookById = async (bookId) => {
  return await bookRepository.deleteById(bookId)
}

module.exports = {
  deleteBookById
}
```

## 6 - Events

None.

## 7 - Response

Once all our error handling will be taken care of by the `isAuthenticated` and `bookPermission` middleware. If there are no errors, we should show a success message like the following.

```javascript
const globalResponseDto = require('../../responses/globalResponseDto')
const catchException = require('../../utils/catchExceptions')
const bookService = require('../../domain/services/book.service')

/**
 * Deletes an existing new book listing.
 */
const deleteABook = catchException(async (req, res) => {
  const book = await bookService.deleteBookById(req.params.id)

  res.json(
    globalResponseDto({
      status: 'success',
      code: 200,
      message: `The book with the id: ${book.id} was successfully deleted.`,
      data: null,
      errors: null
    })
  )
})

module.exports = deleteABook
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.restfulnode.com/part-3/chapter-9/6-deleting-a-book-listing-by-id-implementation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
