This tutorial and associated code was written by Nazmus Nasir. You can find the code on https://github.com/nlinux1/CRUD-Example-with-ExpressJS-and-Mongoose.
This tutorial will teach you to create CRUD API end points using NodeJS, ExpressJS, MongoDB, and Mongoose. The example we will be using is a database containing all of your captured Pokemon! You can change the file names, keywords, and code to reflect your own topic.
This tutorial assumes that you have your application already started and connected to a MongoDB collection. We'll only cover creating the controller and API endpoints in Express.
Remember to checkout the Resources section below for associated downloadable on Github and more!
To start, make sure you create a directory titled controller at the root level. And another called api within your routes directory.
Once the folders are created, inside the /controller directory, create a file called pokemonController.js. You can name it anything you want.
Inside the /routes/api directory, create a file called pokemon-api.js. Again, you can name it anything you want.
In order for our new api route to be useful, we need to tell our app.js to look for and accept visitors to those routes. In app.js, require the pokemon-api.js file along with your other routs:
Then after your indexRouter is defined, tell your app to use the newly created route:
Now that our app routes are set up, we need to tell our new controller to do stuff. We should first apply some basics to the file by telling it to look at our model and to export a custom class as a service:
The module exports is exporting this as a service which can be imported into our API file later on.
Now that we have our controller set up properly, let's write a quick static method to READ all documents within our collection:
The listAll()
method is using our model to find and return ALL documents within the collection specified in our model. Now we need to tell our API file to call this method.
Before we write code to call the listAll()
method from our controller, let's initialize our API file first.
The first two lines are creating the ExpressJS router. The next two lines are looking at our Controller and creating a service called pokemonService
which we can access for all of our API routes.
But before we create our first route, let's add some more code and set the Content-type of our responses as application/json. This will the consumers of our API that all responses sent are in JSON.
The next()
method just tells our script to keep moving after router.use()
has completed. Now we create our first API route to GET all of our data.
Let's create a simple GET method which access the pokemonService and sends a response as a JSOn string.
Let's run the app with npm start
if you're using NPM and let's go to the route via http://localhost:3000/api/pokemon. The domain and route can be whatever you specified it to be:
If you already had a document within your collection like I did, you will see data outputted. If you're not using a JSON formatter like I am, you will just see a long JSON string and that's perfectly normal.
If you don't have a document yet, let's create one with our POST API!
Now that we know how to read all the documents, let's do the C in our CRUD API.
In our Controller, create a new static method called create()
which takes an object as a parameter:
Our create(obj)
method looks for an object sent by the API and creates a new Pokemon object using our model. Then we save the newly created Pokemon object and return its value to our api.
We need to send some data to our controller from our API, but we need to receive the data using the POST method. In our pokemon-api.js file, create a new route with the post method as shown:
The item
object reads the request and assigns the values sent in the body of the request to the four properties that our model specifies. We then send the item to our pokemonService.create()
method to post this data. Once done, we receive a response and send it back to the consumer of the API as stringified JSON.
To test our POST API, you can use any REST API application. I am using Postman. In Postman, I send data to http://localhost:3000/api/pokemon via POST with four sets of data (name, nickname, combatPower, and hp).
If all is set up correctly, when you send this request, you will get a JSON object back confirming your input along with an _id which was automatically generated by MongoDB.
You can also use your browser to test and make s ure the new document now shows up.
We're now ready to create our UPDATE method in our controller. Unlike the POST method which looks for an object as an argument, the UPDATE method will also need an _id parameter so that we target the correct document in our collection.
The change()
method uses the ID to find one document from our collection. It then sets the data object received and saves it. Once completed, it returns everything to the API. Let's call it.
Our PUT method in our API file will receive a request via PUT to change one specific document in our MongoDB Collection. The method will then call the static change()
method in our
controller to make the change and output the changed object in JSON.
The PUT request looks very similar to our POST request. The only difference is that the route is looking for a :pokemonid
which is the MongoDB auto-assigned ID for that specific document.
The other slight difference is that when calling our controller method, we send in an id along with the object data.
If our PUT request is successful, the response will send the stringified JSON of the returned object.
Just like our POST, we can test the PUT API in Postman. Our setup will look very similar. Wee're sending the same data with the exception of passing the ID in the URL. You can get the ID from a GET call if you're wondering where I got my id.
The API request will return a response containing the changed data if accepted. You can verify again with a GET call or by refreshing your browser.
We finish this example with the DELETE controller, the last piece left of our CRUD application. The DELETE is fairly easy, you just need to pass in the ID that needs to be removed and use the Mongoose method .findByIdAndRemove()
.
Once deleted, the method sends the deleted data back as confirmation.
Setting up the DELETE router is also simple. Just like the PUT router, we need to send in the ID that needs to be deleted, but this time, we don't need to send a ny other data.
If successful, it sends a response with the stringified JSON object that was deleted.
Testing the DELETE API is as easy as changing your Postman request to DELETE, and sending in the API URL with the ID at the end. No need to send any headers or body or anything else. If successful, the response will be the deleted object.
You can also test the delete by either using a GET request or refreshing your browser to confirm that the document has been deleted.
See the code on https://github.com/nlinux1/CRUD-Example-with-ExpressJS-and-Mongoose.
Want the source code? Get it on my Github: https://github.com/nlinux1/CRUD-Example-with-ExpressJS-and-Mongoose