How to run internal and external APIs with Fastify

Explain an example of API integration in Fastify.js.

overview

Fastify.js is a lightweight, high-performance web application framework for Node.js, 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 with Fastify.js using the following versions.

Fastify.js v4.0.0
nodejs v19.7.0

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

of course. As an example of running the API from the front end, I will add how to use the Fetch API using JavaScript.

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.

Before implementing the server side, run the following command to install the @fastify/static plugin.

npm install @fastify/static@latest

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

server.js

// import the module
const fastify = require("fastify")({ logger: true });
const path = require("path");
const fs = require("fs");

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

fastify.register(require("@fastify/static"), {
  root: path.join(__dirname, "views"),
  prefix: "/", // optional: default '/'
});
fastify.get("/users", (req, reply) => {
  // return user data as response
  reply.send(users);
});

fastify.post("/users", (req, reply) => {
  // get user data from request body
  const user = req.body;
  // add user to datastore
  users. push(user);
  // return the newly created user as a response
  reply.send(user);
});

fastify.listen({ port: 3000 }, (err) => {
  if (err) {
    console.error("Error starting server:", err);
    process.exit(1);
  }
  console.log("Server started on port 3000");
});

Commentary

This code builds a basic Fastify server that supports listing and creating users. Below is a detailed description of each part.

  • import module
const fastify = require("fastify")({ logger: true });
const path = require("path");

This part imports two modules, fastify and path.

  • specify the directory that hosts the HTML files
fastify.register(require('@fastify/static'), {
  root: path.join(__dirname, 'views'),
  prefix: '/', // optional: default '/'
})

Here we use the @fastify/static plugin to host static files in a directory called “views”.

  • Temporary data store for storing user data
let users = [];

In this part we define an array to store the created users.

  • routing
fastify.get("/", (req, reply) => {
  reply.sendFile('index.html') // serving path.join(__dirname, 'views', 'index.html') directly
});

Use the fastify.get() method to handle GET requests to the root URL ("/"). When a request comes in, it will return the “index.html” file as a response.

  • Get user data
fastify.get("/users", (req, reply) => {
  reply.send(users);
});

Returns a list of all saved users in JSON format when a GET request to /users is received.

  • Create User
fastify.post("/users", (req, reply) => {
  const user = req.body;
  users. push(user);
  reply.send(user);
});

When a POST request to /users comes in, get the user data from the request body and add it to the datastore. Returns the newly created user in JSON format as a response.

  • Start server
fastify.listen(3000, (err, address) => {
  if (err) throw err
  fastify.log.info(`server listening on ${address}`)
})

Finally, start the server and listen on port 3000. When the server starts, you will see the message “server listening on {address}” on the console.

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.

The final directory structure will look like this:

integration
├── node_modules
│ └── (dependency package)
├── views
│ └── index.html
├── server.js
├── package.json
└── package-lock.json

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
const fastify = require("fastify")({ logger: true });
const axios = require("axios");

fastify.get("/data", async (request, reply) => {
  try {
    const response = await axios.get(
      "https://jsonplaceholder.typicode.com/posts"
    );
    reply.send(response.data);
  } catch (error) {
    reply.status(500).send({ message: "Error occurred" });
  }
});

fastify.listen({ port: 3000 }, (err, address) => {
  if (err) throw err;
  fastify.log.info(`server listening on ${address}`);
});

Commentary

This code creates a Fastify server that gets data from the JSON placeholder API and sends that data as a response.

  • Module import:
const fastify = require('fastify')({ logger: true });
const axios = require('axios');

This part imports two modules, fastify and axios. fastify is a web server framework and axios is an HTTP client library.

  • Route definition:
fastify.get('/data', async (request, reply) => {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
    reply.send(response.data);
  } catch (error) {
    reply.status(500).send({ message: 'Error occurred' });
  }
});

Defines a handler for GET requests to the /data endpoint. Use axios.get inside an asynchronous function to get data from an external API and send that data as a response. If an error occurs, send a response with status code 500 and an error message.

  • Start Server:
fastify.listen({ port: 3000 }, (err, address) => {
  if (err) throw err;
  fastify.log.info(`server listening on ${address}`);
});

Finally, start the server and listen on port 3000. When the server starts, you will see the message “server listening on {address}” on the console.

test

curl http://localhost:3000/data

You can use CURL commands to test the behavior of each endpoint. But make sure your application is running on port 3000. Also, change the host name and port number if necessary.

summary

In this article, we learned how to use Fastify to run our API. Fastify is a fast and efficient framework for building APIs with Node.js. Fastify is known to be fast even compared to other frameworks such as Express and Koa. Fastify has gained popularity as a fast and efficient framework for Node.js API development.