Adding Create, Read, Update and Delete Endpoints
So far the application allows users to read data, the 'R' of CRUDing (Creating, Reading, Updating and Deleting). We will now extend the project with endpoints to add this functionality. In the context of the films API project, an endpoint refers to a specific URL or URI that represents a unique film or an action related to films. Endpoints define the operations that can be performed on film resources.
Each operation in the films API can be associated with specific endpoints:
Create: This operation allows the creation of a new film resource. The corresponding HTTP method is typically
POST
, and the endpoint represents the collection or resource where the new film will be added. For example,/api/
can be used to create a new film.Read: This operation is used to retrieve film resources. The corresponding HTTP method is typically
GET
, and the endpoint represents the specific film or collection of films to be retrieved. For example,/api/
can retrieve all films, and/api/films/:id
can retrieve a specific film by its ID.Update: This operation is used to modify an existing film resource. The corresponding HTTP method is usually
PUT
orPATCH
, and the endpoint represents the specific film to be updated. For example,/api/:id
can be used to update a film with a specific ID.Delete: This operation is used to remove an existing film resource. The corresponding HTTP method is typically
DELETE
, and the endpoint represents the specific film to be deleted. For example,/api/:id
can delete a film with a specific ID.
In a films API, various endpoints are defined to handle different film-related actions and resources. Each endpoint follows a consistent pattern, where the URL structure reflects the purpose of the action and the specific film or collection of films involved.
For example, in a films API, the following endpoints could be defined:
GET /api/
retrieves all films.GET /api/:id
retrieves a specific film by its ID.POST /api/
creates a new film.PUT /api/:id
updates a specific film by its ID.DELETE /api/:id
deletes a specific film by its ID.
By mapping CRUD operations to specific endpoints in the films API, clients can interact with the API in a standardized way, allowing them to create, retrieve, update, and delete film resources easily.
Before we proceed with the CRUD functionality, let's briefly explain what REST calls are. REST stands for Representational State Transfer and is an architectural style for designing networked applications. In REST, resources are identified by unique URLs, and different HTTP methods are used to perform operations on those resources. The four main HTTP methods used in REST are:
- GET: Retrieves data from a specified resource.
- POST: Submits data to be processed to a specified resource.
- PUT: Updates a specified resource with new data.
- DELETE: Deletes a specified resource.
Adding an Endpoint to Create a new Document
In the controller.js
create an an asynchronous function createData
that will be responsible for creating a new document in the MongoDB collection.
Here's an explanation of the code:
The function
createData
takes a single parameterdata
, which represents the data for the new document to be created.Inside the function, there is a
try
block that contains the code to insert the new document into the collection using theinsertOne
method.The
insertOne
method is called on thecollection
object, which is an instance of the MongoDB collection where the documents are stored. It takes thedata
parameter as an argument.The
insertOne
method returns a result object that contains information about the operation, and in this case, we are returning theresult.acknowledged
value.If the document is successfully inserted, it is returned as the result of the
createData
function.If an error occurs during the insertion process, the code jumps to the
catch
block, where the error is logged usingconsole.error
, and a response object with an error message is returned:{ error: 'Failed to create data' }
.
Ensure the new function is exported by amending the export:
With the controller set up we now need a router by adding a POST
route as follows:
As the data is been set in the http headers through req.body
we need to edit index.js
by adding:
Test the pages by making a POST http call in POSTMAN with raw JSON data as a body
payload.
Adding an Endpoint to Update Data
Next we'll add an asynchronous function updateData
that is responsible for updating a document in the MongoDB collection based on its ID. We will need to convert the provided ID into an ObjectId
that is the format that MongoDB can work with.
The
updateData
function takes two parameters:id
represents the ID of the document to update, anddata
represents the updated data for the document.Inside the function, there is a
try
block that contains the code to update the document in the collection.The first line inside the
try
block creates anObjectId
instance by passing theid
parameter as an argument. TheObjectId
is a MongoDB data type used to uniquely identify documents in a collection.The
updateOne
method is then called on thecollection
object to update the document. It takes two arguments: the first argument{ _id: o_id }
specifies the document to update based on its ID, and the second argument{ $set: data }
specifies the updated data to be set for the document.The
updateOne
method returns a result object that contains information about the operation, including the number of documents modified. In this code, we check ifresult.modifiedCount
is equal to0
. If no documents were modified, it means no document was found with the provided ID, so we throw an error usingthrow new Error('No document found with the provided ID')
.If the document is successfully updated, the function returns an object with a success message:
{ message: 'Data updated successfully' }
.If an error occurs during the update process, the code jumps to the
catch
block, where the error is logged usingconsole.error
, and a response object with an error message is returned:{ error: 'Failed to update data' }
.
Again ensure the new function is exported by amending the export:
Add a route in the routes/routes.js
to call this new endpoint. This will be a PUT.
Save and the test the page. As we need an ObjectId
to update we need to send this as a URL parameter, as we did with the getDataById()
example. This should also be made through a PUT call from POSTMAN, with new JSON to update the document.
Adding the Delete Endpoint
Hopefully, adding the delete functionality will be straight-forward given the previous two examples.
We will add a deleteData
to remove a document. Like the update function this will require and objectID to ensure the correct document is removed.
Again the exports need updating to:
Update the router file with a delete endpoint:
Again test with Postman but this time creating a DELETE http call with the objectID as a URL parameter of the document you wish to remove.
Notes on Postman
Postman is a popular tool used for testing and interacting with APIs. It provides a user-friendly interface that allows you to send HTTP requests to API endpoints and inspect the responses.
- Start your Node application.
- Open Postman.
- Create a new request and set the request URL to the appropriate endpoint. For example, to test the
getAllData
function, set the URL tohttp://localhost:your_port/api/
(replaceyour_port
with the actual port number you're running your application on). - Select the appropriate HTTP method for the request (
GET
forgetAllData
,POST
forcreateData
,PUT
forupdateData
,DELETE
fordeleteData
). - Set the request body if required. For
POST
andPUT
requests, you can provide the data to be created or updated in the body. - Send the request and observe the response from the API.
Repeat these steps for each endpoint you want to test, using the appropriate HTTP method and providing the required data in the request body when necessary.
Tip: This Repo will have the code from the above.
Next: Mongoose