How to get started with Node.js and Express
Getting Started
What do you need to know before starting this tutorial?
- JavaScript
- JSON
- Familiar with using command line
What is a backend?
When you go to your Facebook profile, you can endlessly scroll through your newsfeed. Does your computer and browser just have all this information? No, Facebook hosts this information for you in one of their datacenters (a building with a bunch of servers). When you go to Facebook, your browser sends a request to Facebook asking to load the webpage. Similarly, every-time you reach the end of your newsfeed, your browser sends another request to Facebook asking for more information. Facebook’s backend then processes your request, goes to the database to get information for your news feed, and returns a newsfeed catered to you. Essentially, the backend is a part of a website that you don’t see.
Node
What is Node.js?
JavaScript usually runs on the client. For example, web developers often use JavaScript that runs in the browser to create interactive webpages. Node.js is a JavaScript runtime that runs on servers and allows developers to use JavaScript for network applications.
Let’s start off by ensuring we have all the necessary packages installed on your machine. We will first make sure we have node installed. Please note that this section is written specifically for macOS, please check out this article for Windows specific instructions.
- Run “node -v” in terminal
- If you have node installed, you will see something like this:
$ node -vv12.14.1
3. If you see that, that means you have node installed and you can continue to the “Getting your project setup” section. If you do not have node installed, terminal will output “node: command not found.”
4. Go to the Node.js website and click on the download button.
5. Once the download is complete, open the installer you just downloaded, and go through the installation process.
6. If you successfully installed Node.js, you should be able to run “node -v” in terminal and see the version in the output. If you still get “node: command not found”, check out this article and try following the steps there.
Getting your project setup
Now that we have node installed, let’s begin by setting up the project for your awesome backend you’re about to build!
- Create a new folder for your project
$ mkdir [name_of_project] && [name_of_project]
2. From this point, you can use yarn or npm as your package manager. I will provide you with commands for both, so you can pick the one that you would like to use. Let’s begin by creating a package.json file, which holds metadata for our project. You can read more about what a package.json is here.
$ yarn init --yesor$ npm init --y
3. We will use express, a Node.js framework, for web applications. To install express, run the following command:
$ yarn add expressor$ npm install --save express
4. Create a file called app.js, which will be the main entry point into the app. Inside app.js, paste the following code:
5. Let’s update our package.json. Let’s change the “main” entry point to “app.js”. Your package.json should look like this now:
6. We’re all set to have our “Hello World” app up and running! On terminal, type “node app.js”. Then go to your browser, and go to http://localhost:3000/. You should see “Hello World” being served from the backend you just built!
Building a Sample App
Now that we have a “Hello World” Node.js server, let’s build something that serves some simple requests.
What are requests?
A request is when a client initiates communication to the server, and asks the server to do something. Perhaps, the client is asking the server to authenticate a user. Or maybe, the client is telling the server to add a new user. No matter the request, servers and client need a protocol in order to understand each other. One common protocol is the HTTP protocol, and it’s the protocol that we will be using.
HTTP Requests
There are two common types of requests in HTTP that we will use: GET and POST requests.
GET: Fetch a resource from the server
POST: Create a new resource on the server
GET requests may be used to get the list of documents on a user’s Google Drive, whereas a POST request may be used to add a new document to the drive.
API: Application Programming Interface
So, we know that HTTP is the protocol used to communicate between servers, but how does the server figure out how to respond to certain requests. In a HTTP POST body, if there was “add Bob to the list of names”, that makes it clear what we’re trying to do. However, the server doesn’t speak English. This is where an API specification comes in hand. Clients communicate to the server following the rules of the API, and similarly servers understand and respond following the rules of the API. Often times, a JSON format is used for this communication.
An Example API
Let’s come up with our own API to both understand how it works, and to use it as our specification for our example app.
We’ll create a simple sorting app. Our server will take two requests.
GET: /names
Description: Gets a list of sorted names
Response: 200 OK
{
[names]
}
Example Response:
200 OK
{
["Bob Ross", "Charlie Smith", "Dan Garnett"]
}POST: /names
Description: Add a new name to the list
Post Body:
{
"firstName": "[first name]",
"lastName": "[last name]
}
Example Post Body:
{
"firstName": "Larry",
"lastName": "Page"
}
Response: 201 Created
So what does this all mean?
- “GET” / “POST”: Let’s look the the endpoint following the “GET:” and “POST:”. This specifies how to access that resource. We could access it by going to where the server is hosted (an ip/domain name) followed by the route: http://localhost:3000/names.
- “Description”: simply describes what that endpoint is doing. In our case, we can see that when a user hits the “/names” with a get request, they expect back a sorted list of names.
- “Response”: Directly following the response is a what’s called a response code. These are part of the HTTP protocol and lets the client know how the response was handled. You’ve probably seen a 404 error on a website. That code is used to indicate that a resource is missing. Similarly a 200 OK means that the request was successfully completed.
- “Response” / “Post Body”: This is the format the body of the HTTP message. It’s used to show how to format a GET/POST request to the server should look like, and similarly how a server responds to a GET/POST request.
Let’s start building!
Before we begin, there are some some simplifications we’re going to make to understand the basics.
- We will declare all our routes in app.js. For larger projects, it is common practice to use a router and handle different routes in different files. Since this is a simple project, we will simply do everything in app.js. If you want to learn more about routing and everything you can do with them, I encourage you to check out the documentation!
- We will not use a database. Our state will simply live in memory. Databases are great to store information persistently, but for our purposes, we will simplify things by just using memory.
Understanding Hello World
Earlier, we setup our project and got our server to respond to our request with “Hello World!”
app.get('/', (req, res) => res.send('Hello World!'))
Let’s take a deeper look at this line. “app.get()” is used to indicate that it is a GET request. The first argument of the get function is the route. ‘/’ means we’re using the index route. Therefore when we go to http://localhost:3000/, the ‘/’ at the end of that url matches the route specified in the function. Therefore, Express knows to respond to that request with the function specified as the second parameter to the “app.get()” function. Thee request, req, contains information about the request such as what the headers were, or what was in the request body.
Similarly, res is the response. Express passes in the response object, res, for you into the “app.get()” function when it is invoked .We use res to respond to the request. In this case, we are sending back “Hello World” in the response, and that’s why you see “Hello World” when you visit http://localhost:3000/.
app.listen(port, () => console.log(`Tutorial app listening at http://localhost:${port}`))
Now let’s look at why this response is sent to http://localhost:3000/. When we run something from terminal, the server will be hosted at http://localhost:[port]. We specify the port to be 3000 in our app, and when we invoke app.listen(), the port is passed through and the app is hosted at http://localhost:3000/.
The Challenge: Part 1 GET
Earlier, we went over a simple API. Now, let’s implement it! Let’s start by defining a variable that will hold the list of names in memory. We’ll also pre-populate it with some names.
let names = ["Dan Garnett", "Bob Ross", "Charlie Smith"];
The first task: a GET request for a client to receive the names. Reference back at the API specification to determine what route we serve this request at. We first need to sort the list of names, then return it in the response object. Remember, we handle get queries like this:
app.get('/', (req, res) => res.send('Hello World!'));
Stop scrolling here! Try and implement this yourself first, then continue on to see the solution.
Before we look at the solution, let’s learn how you can easily test your solution yourself! We’ll use a tool called Postman in order to send a GET request to our server. Go ahead and download that now!
- Once you have Postman downloaded, click on + next to the …
2. Then in the “Enter Request URL” text box, type in “localhost:3000/names”
3. Before you hit Send, make sure you run “node app.js” in terminal. Then you can hit Send, and see how your server responds to your request!
Solution: Maybe you wrote a sort function, or maybe you simply used the built in sorting function. Either way, your code should look something like this:
app.get('/names', (req, res) => res.send(names.sort()));
What’s happening here? At the ‘/names’ route, we respond with names.sort(). That returns a sorted list of the names array; and therefore, we have successfully returned a sorted list of names.
The Challenge: Part 2 POST
Now, how can we add new names to the list? We have to make a POST request to the server. Once again, reference the API specification for the details on the format of the request. Here are some hints for this part:
- Similar to how we wrote our GET handlers, Use “app.post(…)” for POST requests.
- We need to get the body of the request to get the firstName and lastName fields. You can do that with “req.body”.
- What happens if there is no firstName and lastName fields? We need to respond with an error. Earlier, we learned about response codes. Respond with a 400 Invalid Input in this case. The code snippet below might help:
res.status([fill in with error code]).send([fill in with error string])
Before you look at the solution, try testing it yourself again using Postman. Simply change the GET dropdown to POST and fill in the Body. Remember to restart your server again after saving your file
Solution: We first handle the error case: if the expected fields don’t exist, we respond with an error. Then, we parse the body for the first name and last name and concat it together. This name then gets added to our list of names.
Some Closing Thoughts
You’ve built you very first backend using Node.js and Express, congrats! What’s next? At first, you might consider a simple extensions to the app.
- Sort by last name instead of first name.
- Add an age parameter to the user and an age endpoint that returns the age of a user given their first name and last name.
- Instead of storing all the information in memory, store information in a database.
Hopefully, you’ve learned the basics of Node.js and Express. The possibilities are endless from here, so I encourage you to continue to learn more about Routing and Databases to continue growing your skillset in backend web development.
Further Reading:
Here are some of my favorite resources to learn more about Node.js, Express, and backend web development:
- Routing: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes
- Databases: https://www.prisma.io/blog/introduction-to-databases-jmt9jwidtc2a
- Database Integration with Node.js: https://expressjs.com/en/guide/database-integration.html