RESTful Node.js: A Structured Approach
  • Book Cover
  • About the Author
  • Links and Resources
  • Part I: The Why
    • Foreword
    • Preface
    • Chapter 1: Introduction
      • The Rise of REST and Distributed Systems
      • Problem #1: Structureless Design, Structureless REST
      • The Emergence of JavaScript and Node.js
      • Problem #2: Structureless JavaScript, Structureless Node.js
      • Behold, the Solution: A Structured Approach
      • Summary
  • Part 2: The Theory
    • Chapter 2: REST Origins
      • A Brief History of the Web and the Birth of REST
      • REST vs. HTTP
      • REST - The Abstract Web Architecture
      • HTTP - A Peak at REST's Concrete Implementation
      • What does it mean for an API to be RESTful?
      • Measuring "RESTfulness" with Richardson Maturity Model
      • Pragmatic REST vs Dogmatic REST
      • Summary
    • Chapter 3: RESTful API Design Guidelines and "Best Practices"
      • Theories vs. Principles vs. Guidelines
      • URI Design
      • Method Verbs
      • Status Codes
      • Representational Design
      • Metadata Design
      • Versioning Strategies
      • Security Considerations
      • Documentation
      • Case Study: GitHub
      • Summary
    • Chapter 4: Structured JavaScript Architecture
      • The Monstrous Monolith and Its Downfall
      • Layered/N-Tier Architecture: The Unpopular Proven Way
      • Microservices and Distributed Computing: A Popular Misdirection
      • Summary
    • Chapter 5: The 8 Step Recipe
      • Route Name (URI)
      • Input Request
      • Middleware
      • Validation
      • Domain
      • Events
      • Output Response
      • Test, Refactor, Document
      • Summary
  • Part 3: The Code
    • Chapter 6: Introduction to the Bookstore API
      • The Bookstore API Endpoint Specifications
      • API Design and Code Structure
      • Project Setup
      • Summary
    • Chapter 7: Retrieving Books from our API
      • Retrieving All Books - Planning
      • Retrieving All Books - Implementation
      • Retrieving A Book By ID - Planning
      • Retrieving A Book By ID - Implementation
      • Summary
    • Chapter 8: Adding Authentication to our API
      • Registering the User - Planning
      • Registering the User - Implementation
      • Logging the User In - Planning
      • Logging the User In - Implementation
      • Getting Authenticated User - Planning
      • Getting Authenticated User - Implementation
      • Summary
    • Chapter 9: Adding the Create, Update, and Delete Operations to our API
      • Creating A Book Listing - Planning
      • Creating A Book Listing - Implementation
      • Updating A Book Listing By ID - Planning
      • Updating A Book Listing By ID - Implementation
      • Deleting A Book Listing By ID - Planning
      • Deleting A Book Listing By ID - Implementation
      • Summary
    • Chapter 10: Testing our API
      • Testing the Request
      • Testing the Middleware
      • Testing the Validation
      • Testing the Domain
      • Testing the Event
      • Testing the Response
      • Testing the Controller
      • Integration Test
      • Summary
  • Conclusion
    • Final Words
  • Bonus!
    • Refactoring to HATEOAS
  • Appendix
    • Sources & References
Powered by GitBook
On this page
  • 1 - Route Name
  • 2 - Input Request
  • 3 - Middleware
  • 4 - Validation
  • 5 - Domain
  • 6 - Events
  • 7 - Response
Edit on GitHub
  1. Part 3: The Code
  2. Chapter 9: Adding the Create, Update, and Delete Operations to our API

Updating A Book Listing By ID - Planning

PreviousCreating A Book Listing - ImplementationNextUpdating A Book Listing By ID - Implementation

Last updated 3 years ago

Refer back to section for the API endpoint specifications.

Note that updating a book is quite similar to creating a book, so most of the planning here in this section will be quite similar to the last one.

1 - Route Name

Referring back to the sections under chapter 3, and , we can continue to build upon our books namespace.

We'll use PUT as our method verb of choice since we are updating a resource, and we'll also put the :id as one of the URI parameters.

PUT /api/v1/books/:id

2 - Input Request

Since updating a book will have the same fields as creating one, these are the fields that will be input to us by the user.

  • title

  • description

  • price

  • author

  • datePublished

3 - Middleware

There are two layers of middleware that we will add here.

The first reusing our isAuthenticated helper that will protect us from unauthenticated user from accessing this endpoint.

The second will be a backend service validation check where we'll be checking if the currently authenticated user who is requesting to update said book is fact the owner of that book.

There is also one more thing I would like to add into this middleware, which is a check on whether or not the client's request book ID exists. You'll see how this will be done in implementation section of this endpoint.

You might be wondering why we didn't put this logic somewhere in our domain layer. Well, we could if we wanted to, there wouldn't have been anything wrong with it. Remember that middleware is flexible and can be used in many different ways.

4 - Validation

Same as creating a book, we will need to perform the following validation rules for each of these fields.

  • title - required.

  • description - required.

  • price - required, numeric, minimum number is 1.

  • author - required.

  • datePublished- required, valid date format.

5 - Domain

We'll built on top of the previous section and use the bookModel.

We'll also need some sort of way to make a query to the database in order to find the existing book and update it, so we'll use the bookRepository layer and add the method updateById() to do so.

bookRepository

  • updateById()

On top of that, our controller will call a service to updateBookById(), in this case, it will be the bookService which will use the bookRepository layer.

bookService

  • updateBookById()

6 - Events

None.

7 - Response

Again, very similar to the previous section, except there will be 4 possible responses that can be output with this endpoint.

The first is the authentication middleware that we'll be reusing.

{
  "status": "error",
  "code": 401,
  "message": "Access denied: you must be logged in to access this API endpoint.",
  "data": null,
  "errors": ["You must be logged in."]
}

The second has to deal with whether or not the client has put in the correct fields to pass the form validation.

{
  "status": "error",
  "code": 400,
  "message": "There were errors with the validation",
  "data": null,
  "errors": ["The price must be at least 1.", "The author field is required."]
}

The third is whether or not the client has inputted an existing book ID.

{
    "status": "error",
    "code": 404,
    "message": "That book with the specified ID does not exist."
    "data": null,
    "errors": [
        "Book listing not found."
    ]
}

The fourth is the successful scenario. Do keep in mind that since we are using a PUT request, we'll be returning the entire representation back, meaning that the update response should have the exact same fields as the create response.

{
  "status": "success",
  "code": 200,
  "message": "The book has successfully been updated.",
  "data": {
    "id": "620066e1f84bfd64e7125830",
    "title": "'Harry Potter and the Awesome Book of Nothing",
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "price": 100,
    "author": "J.K. Rowling",
    "datePublished": "December 25, 2010"
  },
  "errors": null
}
Method Verbs
URI Design
Chapter 6, The Bookstore API Endpoint Specifications, API Endpoint #8: Update a Book Listing