Getting Started with REST API: Beginner's Tutorial
Tags: webdev, javascript, beginners, api
Published: 2023-06-29 23:00:00

Hello everyone! In today's article, we will be discussing RESTful APIs, which is a continuation from last week's article on HTTP. Before we begin, I highly recommend reading the previous article to gain a better understanding. You can find it at the following link 👇🏽

**[Understanding HTTP Basics for Beginners](https://dev.to/devlawrence/understanding-http-basics-for-beginners-3f28)**

That being said, Let’s dive right into the article 😉

Before we go further let’s remind ourselves of what an API is 👇🏽

## What is an API?
An Application Programming Interface (API) is a set of rules and protocols that enables different software applications to communicate and interact with each other. APIs act as intermediaries, allowing developers to access and utilize the functionality of another software system, such as retrieving data or performing operations. Let’s take an example 👇🏽

If you are like me and you love listening to music, You can use the Spotify app to enjoy your favorite songs, but did you know that behind the scenes, there's a powerful REST API that lets you request and retrieve Spotify's raw JSON data? It's like having a backstage pass to all the music-related information you could ever want!

So, APIs make it possible for apps to talk to each other, share data, and perform amazing tasks.

## What is a REST API?
REST API (or RESTful API) is basically about communication between client and server and vice versa and it is also a way to build web services that adhere to the principles of REST.

REST stands for Representational State Transfer. It is an architectural style used for designing networked applications.

These APIs allow different software systems to communicate with each other over the internet.

*💡 We are going to see some examples later in this article. So it is completely fine if you don’t understand it yet.*

## Key Principles of REST APIs
Here are some key aspects of REST APIs 👇🏽

1. **Client-Server Architecture**: REST APIs follow a client-server architecture, where the client makes requests to the server, and the server responds with the requested data or performs the requested action.

2. **Stateless**: REST APIs are stateless, meaning that the server does not store any information about the client's state between requests. Each request from the client must contain all the necessary information for the server to understand and process it. And this leads to web applications that are reliable.

3. **HTTP Methods**: REST APIs utilize the standard HTTP methods for performing different actions. The most common HTTP methods used in RESTful APIs are:
    - GET: Retrieves a representation of a resource.
    - POST: Creates a new resource.
    - PUT: Updates an existing resource.
    - DELETE: Removes a resource.
    
    Additionally, there are other methods like PATCH, HEAD, and OPTIONS that have specific uses within the REST architecture.

4. **Resource-Based**: REST APIs are built around resources, which are the entities that the API exposes. Resources can be identified using Uniform Resource Identifiers (URIs), which are typically represented as URLs. For example, **`/users`** can be the URI for a collection of user resources, and **`/users/123`** can represent a specific user with the ID 123. All these things are going to make much sense when we see the practical side of things.

5. **Representation of Resources**: REST APIs use various media types, such as JSON (JavaScript Object Notation), XML (eXtensible Markup Language), or even plain text, to represent the resources being exchanged between the client and the server. JSON has become the most popular choice due to its simplicity and ease of use.

## 🔁 Request and Response Cycle in REST APIs
The request and response cycle in REST API simply involves the exchange of information between a client and a server using the HTTP protocol. The client initiates a request to the server, specifying the desired operation and any required parameters. The server processes the request and generates a response containing the requested data or indicating the outcome of the operation. Let's go through an example to get a better understanding 👇🏽

*💡 This example will be based on the key principles we discussed earlier. So, it is important to understand each of them first before going through this example.*

**Example**
Let’s say we have a REST API for a blog platform, and we want to retrieve a list of blog posts. Here are the steps to achieve that 👇🏽

1. **The** **Client sends a GET Request**
The client initiates a GET request to the server's API endpoint that handles retrieving blog posts. The request may look like this 👇🏽
    
    ```vbnet
    GET /api/posts HTTP/1.1
    Host: example.com
    ```
    
    As you can see above, the client is requesting all blog posts by accessing the "/api/posts" endpoint.
    
    The "Host" header specifies the domain or IP address of the API that the client is visiting. In this case, the client is making a GET request to the "/api/posts" endpoint of the "[example.com](http://example.com/)" domain.

2. **The** **Server processes the Request**
The server receives the GET request and identifies the corresponding endpoint ("/api/posts"). It understands that the client wants to retrieve a list of blog posts.

3. **The Server retrieves Data**
The server accesses the underlying database or data source to fetch the required data. In this case, it retrieves the list of blog posts.

4. **The Server generates a Response**
Based on the retrieved data, the server constructs an HTTP response containing the requested blog posts. The response may look like this 👇🏽
    
    ```jsx
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
       "posts": [
          {
             "id": 1,
             "title": "Introduction to REST API",
             "author": "John Doe",
             "content": "All you need to know about REST"
          },
          {
             "id": 2,
             "title": "Building Scalable APIs with Node.js",
             "author": "Jane Smith",
             "content": "Build Scalable APIs"
          },
       ]
    }
    ```
    
    From the code above, the server responds with a "200 OK" status code, indicating a successful request. The response body contains a JSON representation of the blog posts, including their titles, authors, and other relevant information.

5. **The** **Server sends the Response**
The server sends the generated response back to the client over the HTTP protocol.

6. **The** **Client receives the Response**
The client receives the response from the server. It can then extract and process the data contained within the response body.

If you read the previous article about HTTP, you will get a better understanding of what the response header really is.

Now that we've seen how the request and response cycle works, let's now build our own REST API which will allow us to create, read, update, and delete data using HTTP methods such as GET, POST, PUT, and DELETE.

To accomplish this, we'll need to follow a few steps:

1. Define the resources: Determine what kind of data or entities the API will handle. For example, if we were building a REST API for a blog, our resources could include articles, comments, and authors.

2. Design the endpoints: Determine the URL endpoints that will represent each resource and the corresponding HTTP methods that will be used to perform operations on these resources. For example:
    - **`GET /articles`** to retrieve a list of articles
    - **`POST /articles`** to create a new article
    - **`PUT /articles/:id`** to update an existing article
    - **`DELETE /articles/:id`** to delete an article with a specific ID

3. Implement the server-side logic: Write the server-side code to handle these API endpoints. This involves handling incoming requests, parsing the request data, performing the necessary operations on the data (e.g., querying a database), and constructing and sending back the appropriate response.

4. Test the API: We will be using tools like Postman to test the API endpoints. Send requests to the endpoints and verify that the responses are as expected. Make sure to test different scenarios, such as successful requests, error cases, and edge cases.

5. Document your API: It's important to document your API, including the available endpoints, request/response formats, and any additional details or constraints. This documentation will help other developers understand how to interact with your API.

Now let’s jump into the example proper 😃

- Set up the project:
    - Create a new directory for the project on your favorite code editor (We’ll be using vscode in this article)
    - Open your terminal ( CTRL +  ` ).
    - Initialize a new Node.js project by running the command: **`npm init -y`**.
    - Install Express.js by running the command: **`npm install express`**.

- Create a new JavaScript file, e.g., **`server.js`** or any name you prefer.

- Import the necessary modules and set up the Express.js server 👇🏽
    <pre>
    const express = require('express');
    const app = express();
    const port = 3000; // You can choose any available port
    
    // Middleware to parse JSON requests
    app.use(express.json());
    
    // Define your routes and API endpoints here
    
    // Start the server
    app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
    });
</pre>

- Define your API endpoints
We are going to be breaking this part down into segments for better understanding 👇🏽

   - First Segment
   <pre>
   const express = require('express');
   const app = express();
   const port = 3000; // You can choose any available port
  </pre>

  This segment imports the Express framework and creates an 
  instance of the Express application.

  It also sets the port number on which the server will run. In 
  this case, it's set to 3000, but you can choose any available 
  port.

  - Second segment
   <pre>
    app.use(express.json());
  </pre>
 This line adds a middleware to the Express application. The 
 **`express.json()`** middleware parses incoming requests with 
 JSON payloads and makes the parsed data available in 
 **`req.body`**

 - Third segment
 <pre>
 let articles = [
  { id: 1, title: 'First Article', content: 'Lorem ipsum dolor sit amet.' },
  {
    id: 2,
    title: 'Second Article',
    content: 'Pellentesque ac mi sit amet turpis.',
  },
];
</pre>
This initializes an array called **`articles`** that will store the article objects.
It includes two sample articles as initial data. Each article has an **`id`**, **`title`**, and **`content`**.

- Fourth segment
<pre>
app.get('/articles', (req, res) => {
  res.json(articles);
});
</pre>
This defines a GET endpoint at **`/articles`** that retrieves a list of articles. When a GET request is made to this endpoint, it responds with the **`articles`** array in JSON format.

- Fifth Segment
<pre>
app.post('/articles', (req, res) => {
  const newArticle = req.body;
  articles.push(newArticle);
  res.status(201).json(newArticle);
});
</pre>

This defines a POST endpoint at **`/articles`** for creating a new article. When a POST request is made to this endpoint, it extracts the new article object from the request body (**`req.body`**). The new article is then added to the **`articles`** array using **`articles.push(newArticle)`**. It responds with a status code 201 (Created) and the newly created article in JSON format.

- Sixth Segment
<pre>
app.put('/articles/:id', (req, res) => {
  const articleId = req.params.id;
  const updatedArticle = req.body;
  articles = articles.map((article) => {
    if (article.id === parseInt(articleId)) {
      return { ...article, ...updatedArticle };
    }
    return article;
  });
  res.json({ id: articleId, ...updatedArticle });
});
</pre>

This defines a PUT endpoint at **`/articles/:id`** for updating an existing article. The **`:id`** part in the endpoint URL is a placeholder for the article ID. When a PUT request is made to this endpoint, it extracts the article ID from the URL using **`req.params.id`**. It also retrieves the updated article object from the request body (**`req.body`**). The code then searches for the article with the corresponding ID in the **`articles`** array. If found, it updates the article's properties with the properties from the updated article using the spread operator (**`{ ...article, ...updatedArticle }`**).

Finally, it responds with the updated article object in JSON format.

- Seventh Segment

<pre>
  app.delete('/articles/:id', (req, res) => {
  const articleId = req.params.id;
  const deletedArticle = articles.find(
    (article) => article.id === parseInt(articleId)
  );

   if (!deletedArticle) {
    return res.status(404).json({ error: 'Article not found' });
   }

   articles = articles.filter((article) => article.id !== 
   parseInt(articleId));
   res.status(204).end();
  });
</pre>

This defines a DELETE endpoint at **`/articles/:id`** for deleting an article. The **`:id`** part in the endpoint URL is a placeholder for the article ID. When a DELETE request is made to this endpoint, it extracts the article ID from the URL using **`req.params.id`**. The code then searches for the article with the corresponding ID in the **`articles`** array. If the article is not found, it responds with a status code 404 (Not Found) and an error message in JSON format. If the article is found, it removes the article from the **`articles`** array using the **`filter`** method.

Finally, it responds with a status code 204 (No Content) to indicate successful deletion.

- Eight Segment

<pre>
app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});
</pre>

- This starts the server and listens on the specified **`port`**.
- Once the server starts, it logs a message indicating the server is running and the URL where it's accessible.

Here is the code in full 👇🏽
<pre>
const express = require('express');
const app = express();
const port = 3000; // You can choose any available port

// Middleware to parse JSON requests
app.use(express.json());

// Initialize articles array with sample data
let articles = [
  { id: 1, title: 'First Article', content: 'Lorem ipsum dolor sit amet.' },
  {
    id: 2,
    title: 'Second Article',
    content: 'Pellentesque ac mi sit amet turpis.',
  },
];

// GET /articles - Retrieve a list of articles
app.get('/articles', (req, res) => {
  res.json(articles);
});

// POST /articles - Create a new article
app.post('/articles', (req, res) => {
  const newArticle = req.body;
  articles.push(newArticle);
  res.status(201).json(newArticle);
});

// PUT /articles/:id - Update an existing article
app.put('/articles/:id', (req, res) => {
  const articleId = req.params.id;
  const updatedArticle = req.body;
  articles = articles.map((article) => {
    if (article.id === parseInt(articleId)) {
      return { ...article, ...updatedArticle };
    }
    return article;
  });
  res.json({ id: articleId, ...updatedArticle });
});

// DELETE /articles/:id - Delete an article
app.delete('/articles/:id', (req, res) => {
  const articleId = req.params.id;
  const deletedArticle = articles.find(
    (article) => article.id === parseInt(articleId)
  );

  if (!deletedArticle) {
    return res.status(404).json({ error: 'Article not found' });
  }

  articles = articles.filter((article) => article.id !== parseInt(articleId));
  res.status(204).end();
});

// Start the server
app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
  });
</pre>

- Save the changes in your **`server.js`** file.

- Start the server by running the command **`node server.js`** in the terminal.

- Open Postman or any other API testing tool. (But we’ll be using Postman in this article)

- Use Postman to send requests to your API endpoints:
    - For **`GET /articles`**, send a GET request to **`http://localhost:3000/articles`**.
    - For **`POST /articles`**, send a POST request to **`http://localhost:3000/articles`** with a JSON payload representing the new article.
    - For **`PUT /articles/:id`**, send a PUT request to **`http://localhost:3000/articles/{articleId}`** with a JSON payload representing the updated article.
    - For **`DELETE /articles/:id`**, send a DELETE request to **`http://localhost:3000/articles/{articleId}`**.

*💡 You can leave a question in the comment if you get stuck in part*

## Conclusion
That's all, everyone! Congratulations on reaching the end of this article 🎉 🎉. I understand that everything we've covered might seem overwhelming, especially if you're not familiar with Node.js or Express.js. However, I strongly recommend you revisit the previous week's article and consider watching some tutorials on Express.js and Postman to grasp the basics of how they work. This will help you gain a better understanding of the concepts discussed in this article. You've got this! Have a wonderful weekend, and I'll see you next week 😃