When I build an API, I like to have it as light-weight and scalable as possible. At the same time, I want to be able to easily add or remove features with the least amount of effort possible. Because Node.JS and Express give control over the inner workings of a web application, they are the perfect fit.
What will we build?
We will build a RESTful API for a library. A library has books, accounts, DVDs, and many more things. As I always do, I will approach the problem by building an API for books only, and then scaling it to include all the other library items.
First Rollout: Build a Dumb Server
Before we start writing code, we need to fetch the dependencies. Even though the only dependency is Express, I like to keep a package.json file in case I ever decide to add other dependencies in the future. So, the first thing we will do is create a file called package.json and put the following code in it:
Now open up your terminal or command line and go to the project's directory. Type
to install Express. It will be installed in the node_modules directory.
Now that we have all the dependencies ready, let's create a simple server that will capture requests and respond with a Hello World.
Save the file and run
to start the server. The server should response with the hardcoded data when you try to get a book and should echo back the data when you try to do another operation, such as inserting, deleting, or updating.
From Dumb to RESTful
Before we can use real data in our API, we must understand the two fundamental requirements for every API. These two fundamental requirements are communication and storage.
Communication refers to the way in which data is passed back-and-forth between the server and the clients. Since we are building a RESTful API, our communication protocol is HTTP, which we dealt with using Express.
Storage refers to the medium and format in which data is stored. For example, data can be stored on a database server, in a file, or in memory. To fulfill this requirement, I like to start by using MongoDB to store my data. To access the MongoDB database from Node.JS, we will use an NPM package called Mongoose.
Setting up the Database
Before you start using real data in your API, you need to install MongoDB or use a third-party service like MongoHQ. Please refer to the instructions on the MongoDB website to install MongoDB.
After you install MongoDB, create a database called library_database. Then, add a collection named "books" to the database. Run the database server (mongod), and you should be all set.
Second Rollout: Use Real Data
As always, before we start writing any code, we must have all the dependencies ready. The new dependency that we will introduce for this rollout is Mongoose. To install Mongoose, modify your package.json file to look as follows:
To use Mongoose from our Node.js application, we first need to require it. Change the module dependencies code block to
Then, we need to connect Mongoose to our database. We use the connect method to connect it to our local (or remote) database. Note that the url points to the database inside MongoDB (in this case it is library_database).
Mongoose provides two neat classes for dealing with data: Schema and model. Schema is used for data validation, and Model is used to send and receive data from the database. We will now create a Schema and a Model that adhere to our original data model.
Now we have everything ready to start responding to API requests. Since all of the request/response processing happens in the router, we will only change the router code it account for the persistent data. The new router should look as follows:
Here we go, our REST API is now ready to roll.
As we were building our RESTful API, some interesting patterns emerged. For example, the router code block can be swapped with another router code block to add new functionality. In this case, it makes more sense to enclose our routing logic in a separate file. As our code grows, we will also have more schemas, models, and logic to worry about. All of these will eventually need to move out of the server file.
There are hundreds of ways to improve our code. For demonstration, we will move the routing logic out of the server.js.
First, create a new file called router.js. In that file, create a function named registerRoutes that takes in the Express app and Mongoose as parameters. Then, move all the routing logic from server.js to the newly created function. The contents of router.js will be something like this:
The last step is to register the routes from server.js. All you have to do is require your router and call the registerRoutes method in place of your old router.
Congratulations! You did it. You built a RESTful API. However, having the API is only one step of the journey. The more important lesson that you need to learn is to take your journey one step at a time. First, create a dumb app. Then, make it smarter. Then, refactor. The cycle goes on and on. The moral of this lesson is that refactoring is a crucial step in software development. Just like you cannot build a skyscraper with a shaky fundamental, you cannot build web applications with bad code. Farewell and good luck on your journey.