How to link API with Node.js

Explain an example of API integration in Node.js.

overview

Node.js is a JavaScript runtime, often used to work with APIs. In order to link with the API, it is necessary to send requests and process responses.

Here, we will explain how to link with the API in Node.js using the following versions.

nodejs v19.7.0

In addition, all the code created this time is posted on GitHub.


How to run the API from the frontend

Using an API on the front end is a common scenario and can be easily implemented using the JavaScript Fetch API. The Fetch API is a browser-provided native API that allows you to make asynchronous HTTP (Ajax) requests.

The example below creates a new user by sending a POST request to the /users endpoint created in Node.js.

index.html

<!DOCTYPE html>
<html>
<body>
  <!-- add button -->
  <button onclick="createUser()">Create User</button>

  <script>
    async function createUser() {
      const response = await fetch('http://localhost:3000/users', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ name: 'John', age: 25 })
      });

      if (!response.ok) {
        const message = await response.text();
        throw new Error(`An error has occurred: ${message}`);
      }

      const user = await response.json();

      console.log(user);
    }
  </script>
</body>
</html>

Commentary

This source code will generate an HTML page for creating a user.

  • Define HTML document and add button:
<!DOCTYPE html>
<html>
<body>
    <!-- add button -->
    <button onclick="createUser()">Create User</button>

This part defines the basic structure of the HTML document and adds a button to create a user. The createUser function will be executed when the button is clicked.

  • Define createUser function:
<script>
async function createUser() {
    const response = await fetch('http://localhost:3000/users', {
        method: 'POST',
        headers: {
        'Content-Type': 'application/json'
        },
        body: JSON.stringify({ name: 'John', age: 25 })
    });

This part defines the asynchronous function createUser. This function uses the fetch API to send a POST request to the specified URL (http://localhost:3000/users in this case). In the request body, specify the information of the user to be created in JSON format.

  • Error handling:
    if (!response.ok) {
        const message = await response.text();
        throw new Error(`An error has occurred: ${message}`);
    }

The response.ok property determines whether the response was successful (HTTP status code in the range 200-299). If not successful, generate an error message and throw an error.

  • Response processing and logging:
const user = await response.json();

Parse the response body as JSON using the response.json() method.

server.js

// import the module
const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");

// Temporary datastore for storing users
let users = [];

// set the path of the HTML page
const indexFilePath = path.join(__dirname, "index.html");

// create a request handler
const requestHandler = (req, res) => {
  const { pathname } = url.parse(req.url);

  switch (pathname) {
    case "/":
      fs.readFile(indexFilePath, (err, data) => {
        if (err) {
          res.writeHead(500);
          res.end(`Error loading ${indexFilePath}`);
        } else {
          res.setHeader("Content-Type", "text/html");
          res.end(data);
        }
      });
      break;

    case "/users":
      if (req.method === "GET") {
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify(users));
      } else if (req.method === "POST") {
        let body = "";

        req.on("data", (chunk) => {
          body += chunk.toString();
        });

        req.on("end", () => {
          const user = JSON.parse(body);
          users. push(user);
          res.setHeader("Content-Type", "application/json");
          res.end(JSON.stringify(user));
        });
      }
      break;

    default:
      res.writeHead(404);
      res.end(`404 - Page not found!`);
  }
};

// create and start the server
const server = http.createServer(requestHandler);

server.listen(8000, () => {
  console.log("Server is running on port 8000");
});


Commentary

  • import module
const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");

These lines are the http module for creating an HTTP server, the url module for parsing URLs, the fs module for doing filesystem operations, and the path module for doing path operations. is importing.

  • create a temporary datastore to store users
let users = [];

This line creates an array to store the created users.

  • set the path of the HTML page
const indexFilePath = path.join(__dirname, "index.html");

This line sets the path of the HTML file. __dirname points to the path to the directory of the current module file.

  • create a request handler
const requestHandler = (req, res) => {
  // ...
};

This function handles all HTTP requests sent to the server. It takes two arguments, a request object (req) and a response object (res).

  • handle requests to the root URL ("/")
case "/":
  fs.readFile(indexFilePath, (err, data) => {
    // ...
  });
  break;

When there is a request to the root URL, read the HTML file and return its contents as a response.

  • Handle GET and POST requests to “/users”
case "/users":
  if (req.method === "GET") {
    // ...
  } else if (req.method === "POST") {
    // ...
  }
  break;

A GET request to “/users” will return all stored users. If there is a POST request, create a new user.

  • handle requests to other URLs
default:
  res.writeHead(404);
  res.end(`404 - Page not found!`);

Returns HTTP status code 404 and an error message when a request is made to a URL other than the root URL or “/users”.

  • create and start an HTTP server
const server = http.createServer(requestHandler);
server.listen(8000, () => {
  console.log("Server is running on port 8000");
});

Finally, create a server by calling the http.createServer() method with the created request handler as an argument. Then call the listen() method to make the server start listening on port 8000. After the server starts, print a message to the console.

The final directory structure will look like this:

integration
├── index.html
├── server.js

Once done, run the following command to start the server.

node server.js

Once it’s done, access http://localhost:3000 in your browser. Click the button to create the user. A user has been created. Accessing http://localhost:3000/users will display a list of created users.

test

## get user
curl -X GET http://localhost:3000/users
# create user
curl -X POST -H "Content-Type: application/json" -d '{"id":"1","name":"John Doe"}' http://localhost:3000/users

Send a request to an external API

HTTP client libraries are typically used to send requests to external APIs. Here we use one of them, axios. First, install axios using npm.

npm install axios

external.js

const http = require('http');
const axios = require('axios');

const requestHandler = async (req, res) => {
  if (req.url === '/data' && req.method === 'GET') {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      res.setHeader('Content-Type', 'application/json');
      res.end(JSON.stringify(response.data));
    } catch (error) {
      res.writeHead(500);
      res.end(JSON.stringify({ message: 'Error occurred' }));
    }
  } else {
    res.writeHead(404);
    res.end('Not found');
  }
};

const server = http.createServer(requestHandler);

server.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Commentary

– import the module:

const http = require('http');
const axios = require('axios');

http is Node.js’s built-in HTTP server module, and axios is a Promise-based HTTP client library.

  • define a request handler function:
const requestHandler = async (req, res) => {
  if (req.url === '/data' && req.method === 'GET') {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      res.setHeader('Content-Type', 'application/json');
      res.end(JSON.stringify(response.data));
    } catch (error) {
      res.writeHead(500);
      res.end(JSON.stringify({ message: 'Error occurred' }));
    }
  } else {
    res.writeHead(404);
    res.end('Not found');
  }
};

This function checks the request URL and method and returns the response accordingly. Specifically, when a GET request to ‘/data’ comes, it uses axios to get data from the external API and returns the data in JSON format as a response.

  • Create an HTTP server:
const server = http.createServer(requestHandler);

Use the http.createServer method to create an HTTP server using the request handler function requestHandler defined above.

  • start the server:
server.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Use the server.listen method to start the server and listen for requests on port 3000. After the server starts, you should see the message “Server is running on port 3000” on the console.

test

curl http://localhost:3000/data

summary

I’ve created an HTTP server with plain Node.js only, without using the Express framework. The logic for handling requests is defined in the requestHandler function.

  • Import http and axios modules. http is a Node.js built-in HTTP server module, and axios is a Promise-based HTTP client library.

  • Define the request handler function requestHandler. This function checks the request URL and method and returns the response accordingly. Specifically, when a GET request to ‘/data’ comes, it uses axios to get data from the external API and returns the data in JSON format as a response.

  • Create an HTTP server using this request handler using the http.createServer method.

  • Use the server.listen method to start the server and listen for requests on port 3000. After the server starts, you should see the message “Server is running on port 3000” on the console.

This way, even plain Node.js can implement the basic behavior of an HTTP server. However, if you want to implement complex behavior such as routing or error handling, consider using a framework like Express.