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.