How to use RapidAPI with search parameters in Next.js in a safer way

A beginner-oriented guide for those who want to use APIs with search parameters safer with Next.js

How to use RapidAPI with search parameters in Next.js in a safer way

🔓 What you'll get from this 12-minute read

  • You'll sharpen your skills with the RapidAPI service and its vast offer of APIs with Axios.

  • You'll get to know the server-side part of Next.js as a preparation for safer API key usage.

  • You'll improve your general API, React and Next.js understanding.

📝 Prerequisites

  • For this tutorial, I am using Next.js which describes itself as a framework for React. Since I am actually making use of the server-side part of Next.js, I recommend reading this tutorial only if you have heard of Next.js in the past. If you have never seen Next.js before, I would suggest going through a quick introduction of what Next.js actually is.

  • I am using TypeScript, which can be described as a syntactical superset of JavaScript. Due to that, you are able to add types to your code, which can help with regards to error safety during the development phase, for example. However, for this tutorial, you are also able to follow without any TypeScript knowledge since I am not diving deep into the TypeScript part. There are some little differences, but I will show you the respective JavaScript approaches for these parts.

  • You should have some basic understanding of Axios. Even though I will explain my examples, it would be helpful if you saw an Axios API call combined with the try and catch syntax before.

🎯 The Objective

As I started my journey to learn more about APIs and their usage, I found multiple general written tutorials which helped me in order to achieve some sort of basic API understanding.

However, I craved more specific API examples for two reason:

  1. I was still struggling with APIs that required search parameters as an input and needed additional exemplified information to this topic.

  2. I didn't know how to secure my API keys, which should be kept secret as you deploy your projects on Vercel, for example.

Due to these problems, I want to share an exemplified approach of how to use an API from RapidAPI's service with search parameters while using Next.js as the underlying React framework.

Please keep in mind that the following isn't necessarily the best approach ever. However, it's one way that works and can help build a deeper understanding when using Next.js with APIs in general.

🚴 RapidAPI

RapidAPI is a hub for a lot of different APIs that developers can use. While there are some APIs which charge money for their usage, there are also a lot of APIs which are free to use with some sort of limit - due to this fact, RapidAPI is great for practical learning projects in my opinion.

As a first step, we want to find a suitable API, which we are going to use for our Next.js API example. Since I am a fan of good music, I found the Lyrics Plus API. This API can be mainly used to - probably not that surprising - find lyrics of songs. This service is declared as Freemium, so you can use it for free to some extent (200 requests per month are free).

In this documentation for the Lyrics Plus API (see the link above), you are able to find different information:

  • On the left hand side, you find the API endpoints which you can choose in order to get the respective information you are searching for. For my example, I am using Get artist's song lyric, which includes a GET method.

  • In the middle, you can see your personal account on the top with a bunch of details below that, which can be quite confusing if you haven't worked that much with APIs and RapidAPI before.

For this part, however, you just have to understand that you have a personal key (X-RapidAPI-Key) which should be kept secret. The X-RapidAPI-Host is the first-level-domain for this specific API.

In this section, you will also find the required parameters, which are song and artist:

Required Parameters (song and artist)

  • On the right side you find an example Code Snippet of how you could use this API for the respective case - I am using the Node.js -> Axios Code snippet. Here you can see that for the url some of the information that we saw in the middle section is used - the X-RapidAPI-Host, your X-RapidAPI-Key, the song parameter as well as the artist parameter.

After clicking on Test Endpoint, you will also be able to see an example response for this specific API call.

✨ Making use of Next.js

Now that we have chosen which API we want to use, the next step is to dive into Next.js in order to build the required API logic. For this part, I won't explain how to initialize a new Next.js project.

Please refer to the official Next.js documentation in order to learn more about initializing your first Next.js application.

❓ Why Next.js?

One of the many advantages of Next.js is the fact that this framework enables an easy server-side connection, which we can also use for our API. This is a safer approach for our RapidAPI key that should be kept secret.

Following this, we will establish a server-side approach which will act as an endpoint in Next.js which we can then call on our client-side in order to get our API response.

Everything that's done on the server-side doesn't get to the client-side. This is why we can use our API key (or other secret information) on the server-side for an overall safer approach; this can't be done directly with just React.

🔧 Setting up the server-side

If you have not worked much with Next.js before, just have this quick information in mind as we approach:

While the React library itself - which you are probably familiar with - just has a client-side on its own, the Next.js framework actually provides a client-side AND a server-side which can interact with each other. Therefore, we will work on both the client-side and server-side.


To start off, we want to create a new file in the project folder in pages/api. You can name this whatever you like - I am going for lyricsHandler.ts (have in mind that you can do that with JavaScript (lyricsHandler.js) as well instead of TypeScript).

At our new lyricsHandler.ts file in pages/api, we want to start to import the needed requirements. For the TypeScript approach, we will import Axios as well specific TypeScript types:

import axios from "axios";
import type { NextApiRequest, NextApiResponse } from "next";

❗ If you are using JavaScript, ignore the import of these two types.

As a next step, I am going to create a handler which checks the API method it receives from the client-side:

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    if (req.method === 'POST') {
        return await lyricsServerSideAPICall(req, res);
    }
    else {
        return res.status(500).json({ message: 'This method is not available.', success: false })
    }
}

If you're using JavaScript, just use req and res as function parameters without the NextApiRequest and NextApiResponse types.

What's happening here is that this function only accepts the POST method - maybe you remember that most standard APIs have some sort of GET or POST method.

After this check, another function gets returned that we will define in a second. If the request to this server-side endpoint is not a POST method, we will return an error message instead.


❗ Wait, why are we using a POST method instead of a GET method?

Bear with me for some more seconds to understand this concept.

The TL;DR-answer to this would be:

While the actual API call on the server-side uses a GET method, the client-side call uses a POST method to allow for easier handling of input parameters - in this case, the song and artist search parameters.


After establishing this asynchronous handler function, we want to create the lyricsServerSideAPICall function that you already saw above. The name doesn't matter. You can name it whatever you want.

async function lyricsServerSideAPICall(req: NextApiRequest, res: NextApiResponse) {
    const body = req.body;
    try {
        const responseData = await axios({
            method: 'GET',
            url: `https://lyrics-plus.p.rapidapi.com/lyrics/${body.song}/${body.artist}`,
            headers: {
                'X-RapidAPI-Key': `${process.env.SECRET_KEY}`,
                'X-RapidAPI-Host': 'lyrics-plus.p.rapidapi.com'
              }
        })
        return res.status(200).json(responseData.data)
    }
    catch (error) {
        return res.status(500).json({ error: 'There is an error at the server-side API call', success: false })
    }
}

❗ If you are using JavaScript, you can again ignore these two types of NextApiRequest and NextApiResponse.

First, we introduce a variable called body that has a value of req.body. This way, we are able to make use of the input that we will inject on the client-side when calling our API.

For this case, you can imagine that our body variable will be an object with the song and artist input.

After that, I am using the try and catch approach, combined with Axios. If you remember back to what you saw in the API documentation on RapidAPI, you will notice that this Axios information seems oddly familiar.

However, there are some differences. Since we are aiming to actually give specific search parameters to our API call, you can see that we changed the url with the help of a Template Literal. This way, we are able to put in the body object which, as mentioned before, will have the respective song and artist values.

Besides that, you can see that I'm using process.env.SECRET_KEY as my personal RapidAPI key. This is an environment variable. You don't have to follow this approach to make it work. You are able to directly put in your API key.

After these steps, I am returning my final API result or catching the error if one occurs.

🔥 Did you know?

With this server-side approach, it's actually pretty convenient to include such environmental variables in Netlify or Vercel as mentioned above. It can help make your API processes relatively safe - combined with the server-side approach we are using.

Thus, the processes that are computed on the server-side don't reach the client-side. Therefore, this whole server-side thinking in Next.js is also quite convenient for including and working with databases, for example.

This safety aspect can be discussed way more in detail, but especially as a beginner who mainly wants to work with APIs on the front-end, this way is a neat middle ground.

🔧 Setting up the client-side

As explained before, I am using a combination of server-side and client-side in order to make my actual API call. After creating the server-side part, we are going to look at our client-side where we will fetch data from our server-side which we just defined.

You don't have to create a specific new file, but you can if you want to. For my example, I am using the index.tsx file, which can be found in pages.

Firstly, we want to import useEffect and useState since we will use both hooks.

import { useEffect, useState } from 'react';

Next, we want to initialize the values we are going to use for our search parameters (song and artist). In addition, I'm also using a state for the final API response. As I'm using TypeScript, I made use of an interface for this case in order to declare the types which will appear in the API response.

interface apiTest {
  name: string
  lyrics: string
}
 const [song, setSong] = useState("aerials");
 const [artist, setArtist] = useState("system-of-a-down");
 const [APIResponse, setAPIResponse] = useState({} as apiTest);

❗ If you are using JavaScript, you can ignore the interface on top as well as <string> and the {} as apiTest.

The next and last step is going to be the actual API call. For this one, you could - for example - use useEffect in order to call the API:

  useEffect(() => {
    async function APIFunction() {
      const body = { song: song, artist: artist };
      try {
        const response = await fetch("/api/lyricsHandler", {
          method: 'POST',
          headers: {"Content-Type": "application/json"},
          body: JSON.stringify(body)
        });
        setAPIResponse(await response.json());
      }
      catch (error) {
        console.error({ error: "something went wrong with the API on the client-side" })
      }
    }
    APIFunction();
  }, [])

As you can see above, I'm performing an API call with the try and await syntax. Before actually starting to fetch the data, we need a body variable that we can assign the search parameters to - in this case, song and artist.

Please keep in mind that you can initialize the body variable as you can see above or like this: const body = { song, artist }. Both approaches do work since the key and corresponding value are named the same for song and artist in this object.

Now that we have this set up, we can actually start the fetching process. You can see that we are reaching out to the /api/lyricsHandler endpoint, which works due to the fact that we created our server-side file in the api folder of Next.js.

Files which are created in this api folder can be reached out through this endpoint mechanism - how comfortable is that!

Followed by the method we see that I'm using POST even though we wanted to perform a GET call initially. That's because we are not reaching out to the actual API just now. Instead, we are talking with the server-side in Next.js that requires this POST method in order to accept parameters which we can send to the server-side (in this case, our body variable with song and artist).

In order to receive the data which eventually reaches us, I'm using the APIResponse state. After finishing this whole asynchronous function, we are pretty much good to go!

To display it on my screen, I simply use {APIResponse && APIResponse?.lyrics} to get the following results for song: 'aerials' and artist: 'system-of-a-down':

4. result.PNG

✅ Conclusion

In the end, we created a connection to the server-side in order to compute our API call while receiving the result on the client-side to successfully display it. With this approach, we are relatively safe to use API keys as environment variables on the server side of Next.js.

📃 Resources