๐ Servers
Node and middleware and so on
Servers block viewer
This block viewer lets you flick through all the existing blocks in the Servers folder so you can choose what parts to add to your pages and what parts you might want to create, revise, or leave out.
It's literally just an alphabetical list of whatever is in this folder.
๐ GET
Learning Objectives
GET /movies should return all the movies
In server.js
, create a GET /movies
endpoint that returns all the movies (see below for some sample data).
app.get("/movies", (req, res) => {
res.send(moviesData);
});
Copy sample movie data
const movies = [
{
id: 1,
title: "The Godfather",
certificate: "18",
yearOfRelease: 1972,
director: "Francis Ford Coppola",
},
{
id: 2,
title: "The Shawshank Redemption",
certificate: "15",
yearOfRelease: 1994,
director: "Frank Darabont",
},
{
id: 3,
title: "Schindler's List",
certificate: "15",
yearOfRelease: 1993,
director: "Steven Spielberg",
},
];
๐งช Run and test
npm run dev
- Open Postman
- Make a GET request to
http://localhost:3000/movies
๐ GET single movie
Learning Objectives
GET /movies/:movieId should return a single movie (that matches the passed movieId)
Sometimes, we do not want to list all the information in one request, maybe we only want to get the information related to a single movie. Imagine a page to display the details of one movie. We’d call the server, get all movies, then filter the one we need client-side. It would be more effective to tell the server to just return the one movie we are interested in.
We will now add a new endpoint to return only a single movie GET /movies/:movieId. In this case, movieId will tell us what movie we can return. The call will be GET /movies/10
and that will return the movie with that has movieId: "10"
.
This endpoint has something different. The endpoint /movies/:movieId
has a dynamic part. The movieId
will vary depending on what the client sends.
In server.js
, create a GET /movies/:movieId
endpoint that returns a single movie. The movieId will be passed as a parameter in the URL.
app.get("/movies/:movieId", (req, res) => {
const movieId = req.params.movieId;
const movie = moviesData.find((movie) => movie.movieId === movieId);
res.send(movie);
});
๐งช Run and test
- Save your changes
- Make a GET request to
http://localhost:3000/movies/10
๐ช๐พ CRUD Challenges
CHALLENGE 1:
Return the old version of the object you updated as well as the new value in the response
CHALLENGE 2:
Validate the request body to make sure the ID can’t be updated and that users can’t add additional fields
CHALLENGE 3:
Persist your changes to file so that you are able to return your updated values even after you restart the server
๐จ POST
Learning Objectives
POST /movies should save a new movie
In order for our server-side to receive and use the data sent by the client, we will need to install and use a middleware.
The JSON middleware makes it easy for our route handlers to read JSON data from the request. If the Content-Type request header indicates that the request body contains JSON data then the middleware calls JSON.parse to convert the request body into a JavaScript data structure.
To register the JSON middleware, add the following to the server code:
app.use(express.json()); // before our routes definition
In server.js
, create a POST /movies
endpoint that saves a new movie. The movie will be passed as a JSON object in the request body.
Step by step if you get stuck
- Add the following code to
server.js
:
app.post("/movies", (req, res) => {
const newMovie = req.body;
moviesData.push(newMovie);
res.send("movie added successfully!");
});
- Open Postman and create a new request.
- Set the Request Type to POST.
- Enter the URL for your endpoint, which should be http://localhost:3000/movies.
- Set the Body Type to raw and format to JSON (application/json).
- Enter the movie Data in the body of the request as JSON:
{
"id": "13",
"title": "Boyhood",
"certificate": "15",
"yearOfRelease": 2014,
"director": "Richard Linklater"
}
- Click Send.
- You should see the movie you just created in the response.
๐จ PUT
Learning Objectives
PUT /movies/:movieId should update a movie (that matches the passed movieId)
This means that PUT /movies/2
should update an movie with the id 2
and return 200
with JSON { success: true }
to the user.
The code should look something like this:
app.put("/movies/:movieID", (req, res) => {
console.log("PUT /movies route");
});
Remember, you have got to update the movie, not add it to the list.
Test that your API works by updating one of the movies.
๐ฎ ๐งช Test Examples in Postman
Learning Objectives
You will need to create an account with Postman to complete this task. Follow along with the video Writing Tests in Postman with Examples.
Test your movies API
Given a user wants to see all the movies, when they make a GET request to
/movies
, then they should receive a list of all the movies.Given a user wants to see a single movie, when they make a GET request to
/movies/:movieId
, then they should receive a single movie.Given a user wants to add a movie, when they make a POST request to
/movies
, then they should receive a success message.Given a user wants to update a movie, when they make a PUT request to
/movies/:movieId
, then they should receive a success message.
Building the server
Learning Objectives
The first thing we need to do is build our server. You will often need to build a server when writing back-end code. You can write a server in plain JavaScript, but Express is simpler to work with.
1. Create a server.js
file
Let’s build our server! In your project, create a new file called server.js
. This is where all our server code is going to live.
touch server.js
2. import
the express
library
We just installed Express, but we need to make sure it is included in this file specifically so we can use its methods. In Node.js, when you want to use Express in another file, you must import
it.
To require Express, write the following inside server.js
:
import express from "express";
โ ๏ธ CommonJS legacy
Sometimes you will see require
instead of import
. This is because require
is the old (CJS) way of importing packages in Node.js and not all environments (like runkit) are updated yet. If you see require
in the curriculum, probably use import
instead.
CJS syntax: const express = require("express");
MJS syntax: import express from "express";
3. Initialise the server
To initialise our server, we need to call the express()
function. This will create an Express application for us to work with.
Add the second line of code to your server.js
file:
const express = require("express");
const app = express();
4. Start ’listening’ for potential requests
One more step left, we need to set a port for our server to listen to. Think of a port as a door number: any requests that come to the server will come via that door. Setting a port will allow us to find where our server is running.
We use the app.listen
method to do this. This method takes two arguments: a port and a callback function telling it what to do once the server is running.
Need clarification? Read more about the
app.listen
method in the Express documentation.
We’re going to run our server on port 3000
, and add a console.log
in the callback function. Update your server.js
file, calling the app.listen
method:
5. Switch the server on!
You’ve built your server, but it isn’t running yet. We need to run a command in
the terminal to do this. We are going to use the node
keyword to run the
server file.
Type the following command in your terminal:
node server.js
If you see this, congratulations! You have built yourself a server!
6. npm script
To exit the running the server, type ctrl + c
. Instead of running the server with node server.js
everytime, we can create an alias for it in package.json
.
Under the scripts
property, add start: node server.js
. We can now run our server using npm start
which will be an alias (a shortcut) to node server.js
.
Go to the terminal and type npm start
and make sure that the server still runs.
Communicating with the server
Learning Objectives
Now that we’ve built the server, we need to communicate with it. We are going to control the server with handler functions.
What is a handler function?
When a request reaches the server, we need a way of responding to it. In comes the handler function. The handler function receives requests and handles them, hence the name.
The handler function is always called with a request
and response
object. The response object is what gets sent back to the client. It contains the information that gets displayed in the web page. You can decide what to send back in your response.
What does a handler function look like in Express?
The get()
method is one of the methods used to define a handler function in Express. It takes two parameters: the endpoint at which to trigger an action, and the handler function that tells it exactly what to do.
Here’s an example:
// req is the Request object, res is the Response object
// (these are variable names, they can be anything but it's a convention to call them req and res)
app.get("/", (req, res) => {
res.send("Hello World!");
});
Here, we are telling our server to respond with “Hello World!” when someone tries to access the webpage.
1. Create your own handler function
Add a handler handler function to send back a message to the client. To do that, use the Express send()
method. This will update the response object with the message.
Update your handler function:
console.log
the request
object inside the handler function.
- Restart your server
- Send the request again with Postman
- Go to your terminal to see what it looks like.
You should see a lot of data come through!
2. Check it out in Postman
Quit your server in the terminal with ctrl + c
. Then restart it to run your new changes.
node server.js
- Open Postman
- Send a
GET
request tohttp://localhost:3000
.
If you see your message in Postman, congratulations! You just sent your first response from the server.
Checkpoint
Do you understand all these terms? You should be able to see examples of them in Postman
CRUD
Learning Objectives
We will build a CRUD API. CRUD stands for Create, Retrieve, Update, Delete. If you think about it, this is what most applications do:
โจ Create some “resources” ๐ Retrieve them (GET them) ๐จ Update them ๐๏ธ Delete them
๐ฏ Goal
Our API will manage movie data. It will:
โจ Create a new movie, ๐ Retrieve a list of movies or a single movie
We will build these endpoints:
GET /movies should return all the movies
GET /movies/:movieId should return a single movie (that matches the passed movieId)
POST /movies should save a new movie
๐ Fork the Node-Starter-Kit repo and clone it to your computer. Then run npm install
to install the dependencies.
CRUD Again
Learning Objectives
We are building a CRUD API. CRUD stands for Create, Retrieve, Update, Delete. If you think about it, this is what most applications do:
โจ Create some “resources” ๐ Retrieve them (GET them) ๐จ Update them ๐๏ธ Delete them
๐ฏ Goal
Our API will manage movie data. It will:
โจ Create a new movie, ๐ Retrieve a list of movies or a single movie ๐จ Update a movie
We will build this endpoint:
PUT /movies/:movieId should update a movie (that matches the passed movieId)
๐ You should already have a project using the Node-Starter-Kit. If not, do last week’s prep before you go on.
Install Postman
Learning Objectives
Install Postman
Troubleshooting
If you get:
error while loading shared libraries: libgconf-2.so.4: cannot open shared object file: No such file or directory
You may first need to run this in the terminal:
sudo apt-get install -y libgconf-2-4
If you get a blank screen when you open Postman, try logging out of the app and choosing “Use the Lightweight API Client” instead.
For now you will only need the Lightweight API Client.
Alternatives
If you have an old computer you might find Postman being very slow or becoming unresponsive. In this case you could try:
- Thunder Client: this VS Code extension has a similar user interface to Postman
- Hoppscotch: this web app runs in the browser.
Introduction to Express
Learning Objectives
We have already learned about the Node.js runtime environment and how it allows us to run JavaScript code outside of the browser. We have also learned about the Node Package Manager (npm) and how it allows us to download and use other people’s code in our own projects.
Now we will learn about Express, a Node.js framework that helps us to build web servers and APIs.
๐๐ผโโ๏ธ What is a web server?
A web server is software that accepts requests for web pages, assets, APIs, and other network resources from client programs like web browsers. When a browser requests a web page, the server finds the desired content and returns the appropriate response.
๐บ๏ธ Explore the web server
Let’s investigate a web server made in Node.
Explore 5m
Investigate the different parts of the Node App
require
on Line 3express()
on Line 5app.get()
on Line 12, 26 and 20app.listen()
on Line 29response.send()
on Line 13 and Line 17response.json()
on Line 22
Can you work out what each those lines are doing? Write down your predictions.
๐ Stretch Goals: make and run a local copy
๐๏ธ Run the Simple Server locally
Set up your copy 5m
cd
into the cyf-simple-express
directory.npm install
to install the dependencies.npm start
๐ก
Localhost
http://localhost:3000
๐ ๐ฟ Modify the Server
Poke around (10m)
Now try to modify the server.js
code to do something different.
Examples:
- Say “Hello Margarita”, instead of “Hello thar!”
- Make it return an array of strings as json.
- Make it return the current time
- Advanced: make it return whatever you want!
Make a Node Project
Learning Objectives
๐ Create a new repo
1. Go to github.com/new and choose these settings (click to expand):
Question | Answer |
---|---|
Repository template | No template |
Owner | YOUR_GITHUB_USERNAME |
Repository name | Express-101 |
Description | My first Express web server |
Visibility | Public |
Initialize this repository with: | :white_check_mark: Add a README file |
Add .gitignore | Node |
Choose a license | MIT License |
- Click Create repository
โ Clone your repo
Clone your newly made repo to your local machine. You are going to be working in this folder for the rest of the study session.
Initialize your project
๐ Build your project from scratch
- Open your project in VS Code
- Open the terminal
- Run
npm init -y
to initialize your project - Run
npm install express
to install Express - Commit your changes and push them to GitHub
Start your README
๐ Every repo needs a readme
- Open README.md in VS Code
- Add a title and description
- Add a link to the Express documentation
- Write a sentence about what you are going to build
- Commit your changes and push them to GitHub
Query Parameters
Learning Objectives
So, what is a query parameter?
A query string is the part of a URL (Uniform Resource Locater) after the question mark (?). It is meant to send small amounts of information to the server via the url. This information is usually used as parameters to query a database, or maybe to filter results.
Here is an example of a URL with query strings attached: https://stackabuse.com/?page=2&limit=3
โ Detect Query Parameters
Try sending different responses at different endpoints. Remember the app.get()
method? To set up routing in your server, we need to repeat this method with different endpoints.
app.get("/", (req, res) => {
let searchQuery = req.query.search;
res.send("Hello World! You searched for " + searchQuery);
});
Test this endpoint with query parameters: http://localhost:3000?search=hello
Now your turn!
Respond 10m
Add some code so that your server returns the amount of chocolate that you want from your /chocolate
endpoint.
๐งช Acceptance Criteria
Given a chocolate endpoint
When I load http://localhost:3000/chocolate?amount=3
Then I see the message “Gimme 3 chocolates!”
โโ Multiple Query Parameters
What if we want to detect and read multiple parameters? If we use a URL from earlier as an example, here is how we would send multiple query parameters:
Here we have one parameter called “lat” and another “lng”. The first parameter starts with ? All subsequent parameters start with &.
Here is how we would do that in Node:
app.get("/json", (req, res) => {
let lat = req.query.lat;
let lng = req.query.lng;
res.send(`You searched for Lat: ${lat} and Lng: ${lng}`);
});
Compute 10m
Add some code so that your server takes 2 values that we will multiply together and return the value.
๐งช Acceptance Criteria
Given a multiply endpoint
When I call http://localhost:3000/multiply?value1=2&value2=10
Then it returns a value of 20
Routing
Learning Objectives
At the moment our server only does one thing. When it receives a request from the /
endpoint, it sends back the same response: “Yay Node!”.
๐ก tip
However by making use of endpoints, we can make the server send different responses for different requests. This concept is called routing.
What is an endpoint?
An endpoint is the part of the URL which comes after /
. For example: /chocolate
is the “chocolate” endpoint. It’s the URL to which you send a request. It’s the end point of the resource path.
What is a URL?
Create your own endpoints and send different responses
We’re going to try sending different responses at different endpoints. Remember the app.get()
method? To set up routing in your server, we need to repeat this method with different endpoints.
For example:
app.get("/", function (req, res) {
res.send("Hello World!");
});
app.get("/chocolate", function (req, res) {
res.send("Mm chocolate :O");
});
Explore 5m
/node
and another one when it’s /codeyourfuture
.Set up Render
Learning Objectives
Let’s try out using Render to host our Node.js application. There are many platforms that you can use to host your Node.js application, but we’re using Render right now because it’s free. If your cohort has found a better option, please use that, and contribute your setup guide back to the curriculum.
Set up Render
- Fork https://github.com/CodeYourFuture/CYF-React-Express-Template
- Create an account with Render and choose GitHub as your auth.
- Create a new Web Service and choose Build and deploy from a Git repository
- Connect your forked repo to Render