DEV Community

Cover image for Getting Started with REST API: Beginner's Tutorial
Amrasakpare Lawrence
Amrasakpare Lawrence

Posted on

Getting Started with REST API: Beginner's Tutorial

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

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 πŸ‘‡πŸ½

    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" 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 πŸ‘‡πŸ½

    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 πŸ‘‡πŸ½

    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}`);
    });
    
  • Define your API endpoints
    We are going to be breaking this part down into segments for better understanding πŸ‘‡πŸ½

    • First Segment
      const express = require('express');
      const app = express();
      const port = 3000; // You can choose any available port
      

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

    app.use(express.json());
    

    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
      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.',
      },
      ];
      
      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
      app.get('/articles', (req, res) => {
      res.json(articles);
      });
      
      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
      app.post('/articles', (req, res) => {
      const newArticle = req.body;
      articles.push(newArticle);
      res.status(201).json(newArticle);
      });
      

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
    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 });
    });
    

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
  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();
  });

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
app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});
  • 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 πŸ‘‡πŸ½

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}`);
  });
  • 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 πŸ˜ƒ

Top comments (2)

Collapse
 
volodyslav profile image
Volodyslav

Thanks for sharing 😊 I just know a little about Node is and Express js so it's a little bit hard for me right now πŸ˜… however your explanation about Rest API is really useful for my Django projects 😁

Collapse
 
devlawrence profile image
Amrasakpare Lawrence

πŸ˜…..I'm glad you enjoyed it.