Hey there,
I will show you how to set up a Rest API with Node and Express. I hope you can learn something from this tutorial and I can learn something with your feedback.
Requirements:
- Node installed (Documentation).
- Yarn (Documentation).
- Insomnia (Download).
- Visual Studio Code (Download).
Let's go!
What is Rest?
REST, or REpresentational State Transfer, is an architectural style for providing standards between computer systems on the web, making it easier for systems to communicate with each other. REST-compliant systems, often called RESTful systems, are characterized by how they are stateless and separate the concerns of client and server. We will go into what these terms mean and why they are beneficial characteristics for services on the Web.
Reference.
What is API?
API is the acronym for Application Programming Interface, which is a software intermediary that allows two applications to talk to each other. Each time you use an app like Facebook, send an instant message or check the weather on your phone, you’re using an API.
Reference.
Starting the project:
The first step will be creating a folder to save our project.
$ mkdir nodejs-express-setup
$ cd node-express-setup
Next step, we will create the package.
$ yarn init -y
I recommend you to use the flag -y if you do not want to answer the questions. This flag means you will accept to use the default options.
You can find more information about yarn init in Yarn cli or using the command line $ yarn --help init
in your console.
Checking the folder "nodejs-express-setup" you will find a file named package.json, probably you are making this question...
What is package.json?
The package.json file is kind of a manifest for your project. It can do a lot of things, completely unrelated. It's a central repository of configuration for tools, for example. It's also where npm and yarn store the names and versions for all the installed packages.
Reference.
In addition, you can find some information and tips in Yarn package-json
I hope this information helps you to understand how works package.json.
Setting up the Express.js and nodemon with sucrase.
Why do we need to install this framework?
Okay, let's start to imagine a mobile app or a web application, they will connect to an API every time these apps need to communicate with our back-end, this framework will make our work creating an API easier providing many HTTP utility methods.
Happy to listen to that... Right?
Now that you know the reason for installing this framework, we can proceed with the installation by running the command line below:
$ yarn add express
We will install the sucrase and the nodemon libraries before proceeding with the express.js explanation.
$ yarn add sucrase nodemon -D
The flag -D means will install this library as a dev dependency. Packages are as a dev dependency are only needed for local development and testing. You can read more here.
We need to create a file named nodemon.json:
$ touch nodemon.json
And then add the following lines to the nodemon.json:
"execMap":{
"js": "sucrase-node"
}
This config will define our own default executables using the execMap. We are informing to nodemon to compile using sucrase before to run our code and it will happen every time a js file is executed.
What is sucrase and nodemon?
Sucrase is an alternative to Babel that allows super-fast development builds. Instead of compiling a large range of JS features to be able to work in Internet Explorer, Sucrase assumes that you're developing with a recent browser or recent Node.js version, so it focuses on compiling non-standard language extensions: JSX, TypeScript, and Flow. Because of this smaller scope, Sucrase can get away with an architecture that is much more performant but less extensible and maintainable.
Reference.Nodemon is a utility that will monitor for any changes in your source and automatically restart your server. Perfect for development.
Reference.
Nodemon will make our development faster than normal because it will restart the server automatically every time the code is saved.
With both libraries installed, we need to make one more change.
Edit the package.json adding the following lines:
...
"license": "MIT",
"scripts": {
"dev": "nodemon src/server.js",
"build": "sucrase ./src -d ./dist --transforms imports",
"start": "node dist/server.js"
},
"dependencies": {
...
},
...
In this situation, scripts will make it easier to execute some longs commands.
For example, we can easily execute the command $ nodemon src/server.js
with the command $ yarn dev
.
Before executing this command line we need to create the server.js.
Setting up the server.js
In this topic, we will start to learn how to use the HTTP requests. All the routes created will be in server.js.
We need to create a folder named src and the file server.js:
$ mkdir src && cd src && touch server.js
and then add the following lines in server.js:
import express from 'express';
class Server{
constructor(){
this.app = express();
this.server();
}
server(){
this.app.listen(3333);
}
}
export default new Server();
In the code above, it has the attribute "this.app" to receive all the express methods and the server method to listen to the requests from the port 3333.
We can start the server now, you should go to your console to digit the command line below:
$ yarn dev
In routes, we will create the routes HTTP get, post, put, delete requests. And also we need to add the array to test our requests.
import express from 'express';
const users = ['User01', 'User02'];
class Server{
constructor(){
this.app = express();
this.server();
this.routes();
}
routes() {
}
server(){
this.app.listen(3333);
}
}
export default new Server();
The first line will be added in routes() is the express.json():
...
routes() {
this.app.use(express.json());
}
...
The express.json is necessary to receive the HTTP post and put requests with a JSON object. You will understand better when we start to see the HTTP post and put requests examples. You can read more here.
Before continuing, we need to install the cors library:
We will use this library for future tutorials using this project.
Add the following lines:
import express from 'express';
import cors from 'cors';
....
class Server{
constructor(){
...
}
routes() {
this.app.use(express.json());
this.app.use(cors());
}
...
}
export default new Server();
What is cors?
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.
Reference
This library is necessary to allow other applications to make requests to our API.
Routes HTTP get, post, put, and delete requests:
Get:
We will start doing the HTTP get request. In this example, we will use a route without params or queries.
...
routes() {
this.app.use(express.json());
this.app.get('/users', (req, res) => {
return res.json(users)
})
}
...
Open your browser and try to access the URL (http://localhost:3333/users) to receive an array with "'User01', 'User02'". The route is expecting to someone to access the path '/users' to return the array by res.json.
Easy, right?
How works the request and response objects?
Request:
The req object represents the HTTP request and has properties for the request query string, parameters, body, HTTP headers, and so on.
Reference.
If we want to send an object in your request we can use req.body and if we want to pass some parameters we can use req.params or req.query. I will explain later about these two parameters.
Response:
The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
Reference.
The response object is basically responsible to provide the data or information every time the application receives an HTTP request. We could provide this data using res.send() or res.json().
A brief explanation of the difference between res.send() and res.json().
Res.send():
This method sets the content-type response header based on the parameter, for example, if it is sending an object, the header will set the content-type to application/JSON but if it is sending a string the content-type will be text/HTML.
You can find more information here
Res.json():
This method sets the content-type response header to application/JSON also if the parameter is non-object it will be converted to JSON.
You can find more information here
If you are passing an object or an array in the parameters you won't see any difference between res.send() and res.json() which in most cases is the kind of parameters we will pass to these methods.
I hope you understood the difference between the two methods. We can move forward to the next explanation.
In the last example, we did a route without params or query, in this example, we will do some routes with req.params and req.query.
Req.params:
This property is very useful when we want to get specific data inside of an array.
Below, we are using the req.params to find the user using the value from the index parameter.
...
routes() {
this.app.use(express.json());
this.app.get('/users/:index', (req, res) => {
const { index } = req.params;
return res.json(users[index])
})
}
...
Open your browser and try to access the URL (http://localhost:3333/users/1) to receive the string "User02". Basically the req.params receive the value through the index parameter and we will return the string based on the array index.
For more information, you can read the documentation
Req.query:
This property looks very similar to req.params comparing the way both works, but the big difference is that it allows us to pass more parameters to the object.
...
routes() {
this.app.get('/searchforusers', (req, res) => {
const { index, name } = req.query;
const getUser = users[index];
return res.json(getUser.match(name))
})
}
...
The first thing changed was the path, we are not passing any parameter anymore but it does not mean we can not use both properties together.
This property is passing the values through two parameters and we are using these parameters to find a specific string in the array.
Open your browser and try to access the URL (http://localhost:3333/searchforusers?index=0&name=User01) to receive the string "User01". In this case, both parameters need to be true to return the desired value because we are trying to find the user based on the array index and if the name and string getUser is matching otherwise it will return null.
For more information, you can read the documentation
Post:
We will learn how to add a new string in our array using HTTP post requests.
Before we start, you should add the following lines in your routes.
...
routes() {
this.app.post('/users', (req, res) => {
const { user } = req.body;
users.push(user)
return res.json(users)
})
}
...
Open your insomnia to test the URL(http://localhost:3333/users) and then you need to add in the JSON body the following line { "user": "User03" }
. In our HTTP request, we are sending through the req.body the string to add in our array.
The path is like the first HTTP get request example but we are using a different method.
For more information, you can read the documentation
Req.body:
This property is very useful because we can pass many parameters inside of the object in our HTTP request.
For more information, you can read the documentation
Put:
Update the strings inside of the array will be easy using the HTTP put requests.
Before we start, you should add the following lines in routes:
...
routes() {
this.app.put('/users/:index', (req, res) => {
const { index } = req.params;
const { user } = req.body;
users[index] = user;
return res.json(users)
})
}
...
Open your insomnia to paste the URL(http://localhost:3333/users/0) and then you need to add in the JSON body the following line { "user": "NewUser01" }
. We are sending the string through req.body to update our array based on the array index.
The HTTP put request is very useful when we want to update the specific string in our array, the parameter index is important to identify which index of the array will be updated with the string received through req.body.
For more information, you can read the documentation
Delete:
If we want to remove a string from our array we can use the HTTP delete request.
Before we start, you should add the following lines in your routes.
...
routes() {
this.app.delete('/users/:index', (req, res) => {
const { index } = req.params;
users.splice(index, 1);
return res.json(users)
})
}
...
Open your insomnia to paste the URL( http://localhost:3333/users/0) and to receive the array without the string "NewUser01". Basically the *req.params receive the value through the index parameter to remove the string from the array based on the array index.*
The similarity with HTTP put requests is notable however it is important to determine which action we are using in our requests.
For more information, you can read the documentation
Conclusion:
In this tutorial, we learned how to create a new node project, setting up the express and the nodemon with sucrase, and how to use the express methods and properties.
And...
Doing an analogy between Dunder Mifflin Paper Company from The Office and the REST API.
HTTP get request is the client asking for information about all the orders pending or just one specific order.
HTTP post request is the sales doing the enrolling of the new client.
HTTP put request is the client requesting for updating the quantity of the papers in the order.
HTTP delete request is the unsatisfied client requesting to cancel the order.
Top comments (4)
nice work thought creating a setup every time you start a project is messy work.
create-express-boilerplate.com/ provide a quick start for initiating the project..
have a look.
Thanks Mohammed for sharing this knowledge!
Good paper. Liked that. Also, gifs are amazing. Love the office team <3
Thank you so much Hasan!
I love them too!😂