Published: 19th August, 2024
Author: Sohan Shashikumar
Read Time: 12 minutes
REST stands for Representational State Transfer
. A REST API
is an Application Programming Interface that adheres to the principles of REST architecture.
In simple terms, an API acts as a bridge between a resource provider and a resource consumer. It
is widely used in applications that follow a
Client-Server Architecture
.
Let's say you want to display information about a movie. You would need to use a service that maintains a record of every single movie and provides an interface for developers like us to interact with. This is the primary purpose of an API.
Depending on the type of request made, we can perform Create, Read, Update, and Delete (often
referred to as CRUD
) operations.
Our demo API will be built with this example in mind!
npm init -y
package.json
file.npm install express
src
directory, and inside that, create a new file
named index.js
. This file will be the main entry point of
our application.
const express = require('express');
const port = 3000;
const app = express();
app.get('/', (req, res) => {
res.status(200).send('Congrats, you just consumed data from a REST API!');
});
app.listen(port, () => {
console.log(`π Express app listening on http://localhost:${port}`);
});
Copy paste the above code in your index.js
file and run the
script using the following command:
node ./src/index.js
Upon running it, you'll see that our app has successfully started and is listening on localhost
on the specified port. Open any web browser and type
localhost:3000
You'll see the message we are sending back.
Congrats, your REST API is functioning as intended!
require()
.
app.get()
with a path, in this case, the root
route, /
. The second argument is a callback function which
will be invoked whenever there's an incoming GET
request to
this route.
request
and
response
object indicated by "req" and "res" respectively.
200
which indicates
that everything went well. Additionally, we are also sending a plain text response.
app.listen()
does this and calls the callback whenever the
app starts successfully.
GET
request!
Our app is very simple, it doesn't do anything except sending a plain text message. Let's change
that by adding more functionality. Keeping the example I gave earlier in mind, we will build a
REST API which users can use to perform the basic
CRUD
operations on movie data.
Create a new file, movies.js
const movies = [
{
name: 'Justice League',
year: 2017,
genres: ['Action', 'Superhero', 'Adventure'],
boxOfficeHit: false
},
{
name: 'Interstellar',
year: 2014,
genres: ['Mystery', 'Suspense', 'Sci-Fi'],
boxOfficeHit: true
},
{
name: 'Top Gun Maverick',
year: 2022,
genres: ['Action', 'Adventure', 'Drama'],
boxOfficeHit: true
},
{
name: 'Oppenheimer',
year: 2023,
genres: ['Thriller', 'Historical Drama'],
boxOfficeHit: true
}
];
module.exports = {
movies
};
In a real world scenario, we would store movies in a database such as
MongoDB,
PostgreSQL
or
Cassandra. But for simplicity and to prevent diverting away from the topic of this blog, we will store
it in runtime memory. We will now proceed to perform
CRUD
operations on this data.
const express = require('express');
const { movies } = require('./movies');
const port = 3000;
const app = express();
app.use(express.json());
app.post('/movies/create', (req, res) => {
const { name, year, genres, boxOfficeHit } = req.body;
if (!name || !year || !genres?.length || typeof boxOfficeHit === 'undefined') {
return res.sendStatus(400);
}
movies.push({ name, year, genres, boxOfficeHit });
return res.json(movies);
});
app.listen(port, () => {
console.log(`π Express app listening on http://localhost:${port}`);
});
movies.js
file that stores all the
movies that we created.
json()
middleware function from express.
This basically populates req.body
for all requests having
the application/json
content type.
app.post()
method. The
callback runs whenever a POST
request is made to
/movies/create
. Notice how we are using app.post() and NOT
app.get()
const express = require('express');
const { movies } = require('./movies');
const port = 3000;
const app = express();
app.use(express.json());
app.get('/movie/:name', (req, res) => {
const toSearch = req.params.name;
const movie = movies.find((m) => m.name === toSearch);
if (!movie) return res.sendStatus(404);
return res.json(movie);
});
app.listen(port, () => {
console.log(`π Express app listening on http://localhost:${port}`);
});
app.get()
. Notice the colon,
:
we are using. It is intentional. It is called a Route
Parameter.
:name
acts as a placeholder for accessing what movie we
need to retrieve. We can call the endpoint like so,
/movie/hello
or
/movie/world
.
req.params.name
will be equal to what was passed when we
called the endpoint.
const express = require('express');
const { movies } = require('./movies');
const port = 3000;
const app = express();
app.use(express.json());
app.patch('/movie/:name/update', (req, res) => {
const toSearch = req.params.name;
const movie = movies.find((m) => m.name === toSearch);
if (!movie) return res.sendStatus(404);
const { year, genres, boxOfficeHit } = req.body;
if (year) movie.year = year;
if (genres) movie.genres = genres;
if (typeof boxOfficeHit !== 'undefined') movie.boxOfficeHit = boxOfficeHit;
return res.json(movie);
});
app.listen(port, () => {
console.log(`π Express app listening on http://localhost:${port}`);
});
app.patch()
. We get the name of
the movie from the route parameter and access the fields that needs to be updated from the
request body.
There is one more operation left, that is deleting a movie. I won't be solving it here. You can take it up as a challenge and do it on your own.
Even if you're unable to, don't worry, all the code will be available on the GitHub Repository. Use it only if you get stuck though!
Your feedback is highly appreciated and will be used to improve the quality of existing & future posts!
What do you rate this post?