DEV Community

loading...
Cover image for REST API with Node and Express in 5 minutes

REST API with Node and Express in 5 minutes

lennythedev profile image Lenmor Ld ・Updated on ・4 min read

Part 2 of Node + Express series

Now that we have our first Node + Express server from Part 1
we can now get some REST!

Rest 🛌😴 ???
Not that rest, but REST (Representational state transfer), which is basically providing an API to clients via HTTP Methods.

rest_api

SPOILER ALERT 😱😜
We can map basic operations like CRUD to certain HTTP methods.
Skip if you don't like spoilers or looking at table confuses you 😵.

CRUD Operation HTTP method URL URL params Request body example
Create POST /items body: {...} POST /items body: {...}
Read One GET /items/:id :id (item id) GET /items/123
Read All GET /items GET /items
Update PUT /items/:id :id (item id) body: {...} PUT /items/123 body:{...}
Delete DELETE /items/:id :id (item id) DELETE /items/123

Note that this is a common way of doing this, but you can also implement, say POST for UPDATE and DELETE. Check out Idempotence in REST for details on that.

Let's get started!

Sample data

First, we need some sample data. Let's use some of the movies 🎞️ in IMDB's top 250, since my movie choices are probably not reliable 🤪

Create data.js file. Feel free to add items, and item details.

// data.js
module.exports = [
    { "id": "tt0110357", "name": "The Lion King", "genre": "animation"},
    { "id": "tt0068646", "name": "The Godfather", "genre": "crime"},
    { "id": "tt0468569", "name": "The Dark Knight", "genre": "action"},
];
Enter fullscreen mode Exit fullscreen mode

module.exports exposes this array to other files

Import file in our server.js file

// server.js
let data = require('./data');
...


// our API routes go here

Enter fullscreen mode Exit fullscreen mode

GET

Get all items
GET /items

server.get("/items", (req, res) => {
   res.json(data);
});

Enter fullscreen mode Exit fullscreen mode

Get one item identified by :id
GET /items/:id

We use Array.find to get the first item that matches the condition,
then display a message if not found.

Note that the item id is a string e.g. tt0110357, so we can compare it using=== directly.
You'll have to parse before comparing, if you are using an integer id.

server.get("/items/:id", (req, res) => {
   const itemId = req.params.id;
   const item = data.find(_item => _item.id === itemId);

   if (item) {
      res.json(item);
   } else {
      res.json({ message: `item ${itemId} doesn't exist`})
   }
});
Enter fullscreen mode Exit fullscreen mode
$ curl http://localhost:4000/items
[{"id":"tt0110357","name":"The Lion King","genre":"animation"},{"id":"tt0068646","name":"The Godfather","genre":"crime"},{"id":"tt0468569","name":"The Dark Knight","genre":"action"}]

$ curl http://localhost:4000/items/tt0110357
{"id":"tt0110357","name":"The Lion King","genre":"animation"}

$ curl http://localhost:4000/items/blahblah
{"message":"item blahblah doesn't exist"}

Enter fullscreen mode Exit fullscreen mode

POST

To encode the body of the request sent by client in a POST message, we need body-parser middleware.
This allows us to use req.body in our route handler

npm install body-parser
Enter fullscreen mode Exit fullscreen mode

Then we import and use it. We'll just accept JSON-encoded body for now.

// server.js

const body_parser = require('body-parser');

// parse JSON (application/json content-type)
server.use(body_parser.json());
Enter fullscreen mode Exit fullscreen mode

Post an item
POST /items

Here, we are getting entire item from req.body since it matches our data,
but note that it is also possible to just get, e.g. req.body.name

// server.js

...
server.post("/items", (req, res) => {
   const item = req.body;
   console.log('Adding new item: ', item);

   // add new item to array
   data.push(item)

   // return updated list
   res.json(data);
});
Enter fullscreen mode Exit fullscreen mode
$ curl -X POST -H "Content-Type: application/json" --data '{"id": "tt0109830", "name": "Forrest Gump", "genre": "drama"}' http://localhost:4000/items

[..., {"id":"tt0109830","name":"Forrest Gump","genre":"drama"}]
Enter fullscreen mode Exit fullscreen mode

PUT

To update an item, we expect client to pass item id in the URL param (req.params.id)
and the updated object in the body (req.body)

Here we simply replace the old one using forEach, but you could apply your own
algorithm to replace an object or an object's attribute in an array of objects.


// update an item
server.put("/items/:id", (req, res) => {
   const itemId = req.params.id;
   const item = req.body;
   console.log("Editing item: ", itemId, " to be ", item);

   const updatedListItems = [];
   // loop through list to find and replace one item
   data.forEach(oldItem => {
      if (oldItem.id === itemId) {
         updatedListItems.push(item);
      } else {
         updatedListItems.push(oldItem);
      }
   });

   // replace old list with new one
   data = updatedListItems;

   res.json(data);
});

Enter fullscreen mode Exit fullscreen mode

Let's say you really think The Dark Knight is a drama 😢 instead of action,...

$ curl -X PUT -H "Content-Type: application/json" --data '{"id": "tt0468569", "name": "The Dark Knight", "genre": "drama"}' http://localhost:4000/items/tt0468569

...{"id":"tt0468569","name":"The Dark Knight","genre":"drama"}...
Enter fullscreen mode Exit fullscreen mode

batman_drama

DELETE

Lastly for delete, we only need id URL param from client.
We filter the array, excluding the item to be deleted.

// delete item from list
server.delete("/items/:id", (req, res) => {
   const itemId = req.params.id;

   console.log("Delete item with id: ", itemId);

   // filter list copy, by excluding item to delete
   const filtered_list = data.filter(item => item.id !== itemId);

   // replace old list with new one
   data = filtered_list;

   res.json(data);
});
Enter fullscreen mode Exit fullscreen mode
$ curl -X DELETE http://localhost:4000/items/tt0468569

[{"id":"tt0110357","name":"The Lion King","genre":"animation"},{"id":"tt0068646","name":"The Godfather","genre":"crime"}]
Enter fullscreen mode Exit fullscreen mode

Complete Code in this link

Quick REST API with Node + Express

hackerman

"Okay, that was nice. But what can I do with this? "

Add a few more CRUD routes, and you have a nice REST API for your clients!

Although, you might have noticed that the changes are not persisted yet
when the server is restarted. 😱

We'll cover this in upcoming articles about File Read/Write and MongoDB. Stay tuned.

Next up:

This article is part of a Node+Express series I'm working on.

For the meantime, if you can't get enough of Node+Express 🤓,
checkout my Node workshop (Gihub repo and slides):

GitHub logo lenmorld / node_workshop

Build a server and API for your next web application, using Node, Express and MongoDB

Node workshop

Create a server + REST API for your next web application!

In this workshop, we’ll discuss concepts and put them to practice with activities, all about web servers The code and concepts here would be a great foundation for your next web project Topics include, but not limited to:

  • Using Node and Express to build a web server and REST API
  • Understanding routing, request and response
  • Implementing CRUD with HTTP methods
  • Building a server-rendered website using templates
  • Connecting to a Cloud NoSQL database: MongoDB Atlas DB
  • User authentication with sessions, cookies and tokens
  • Using external APIs, such as Github Jobs, Giphy, Spotify

Previous Events

Material

Preview slides: Google Drive document

Material: Notion link

Code

to follow workshop:

$ git checkout dev
$ node server.js

to dev latest

$ git checkout master
$
…






Here we discussed:
  • Using Node and Express
  • Routing, request and response
  • Building a REST API
  • Server-rendered templates
  • Connecting to a NoSQL (mongo) database
  • Using external APIs, such as Spotify
  • and much more!

Happy server-ing!

Now, time to get some real rest.
Don't forget to get plenty! 🛌😴

sleep

Discussion (1)

pic
Editor guide
Collapse
vasilevskialeks profile image
Aleksandar Vasilevsk

Great post, here is one more guide on how to do node js rest api codespot.org/how-to-build-rest-api...