This is an step by step article on how to Consume a Rapid API.
Built With 🔑
This project was developed using
Projects
Project | Github | Demo | Other | ||
---|---|---|---|---|---|
Landing | Repo | Description | VideoTutorial, Figma | ||
<!— | Landing | Repo | Description | VideoTutorial, Figma | —> |
Content 🚦
1. Create the Rapid-API React Project
Follow the steps on this previous project to Create a React Project using Vite(recommended)
1
npm create vite@latest react-rapid-api-1
Or, you can also do it with Create-React-App (Vite’s performance is better)
2. SetUp by Customizing the Project
Continue following the steps 1 and 2 on this previous project to Create a React Project using Vite and SetUp the Project by deleting unnecesary files, installing Tailwind CSS, and add App Plugings.
3. Find an API to Consume at Rapid API
I. Login to Rapid API.
II. Add New App on Rapid API.
- APPs > Add New App > give it a name > add app
examle: APPs > Add New App > ‘Movies’ > add app
III. Search for Free API’s
For this tutorial, we Will be using IMDb
Some other Free and cool API’s:
IV. Get Endpoint Information From the IMDb API
A. Go to the Endpoints tab in IMDb
B. Click on Subscribe to Test > select the free option.
C. Select the RapidAPI App previously created above. (Movies)
D. From the dropdown menu on the right, select (Javascript) > fetch
- Copy the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
const url = 'https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr'; const options = { method: 'GET', headers: { 'X-RapidAPI-Key': 'VITE_RAPID_API_KEY', 'X-RapidAPI-Host': 'imdb8.p.rapidapi.com' } }; try { const response = await fetch(url, options); const result = await response.text(); console.log(result); } catch (error) { console.error(error); }
Notice that I am calling a variable:
VITE_RAPID_API_KEY
. This is where its store my actual API Key. For security reasons, You don’t want to expose your API key. ThisVITE_RAPID_API_KEY
it’s commonly saved on a.env
file.
4. Consume the API
I. Paste the code above on App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import "./App.css";
async function App() { // async Function
// API That I Used: https://rapidapi.com/apidojo/api/imdb8
const url = 'https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr';
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': 'VITE_RAPID_API_KEY',
'X-RapidAPI-Host': 'imdb8.p.rapidapi.com'
}
};
try {
const response = await fetch(url, options);
const result = await response.text();
console.log(result);
} catch (error) {
console.error(error);
}
return (
<>
<div className="flex justify-center items-center h-screen w-screen">
<h1 className="text-7xl">Rapid API</h1>
</div>
</>
);
}
export default App;
- Got an Error?…
Make sure to add an
async
function toApp
function. this is because the code has anawait
keyword.
II. Modify the App.js
to Fix Error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { useEffect } from 'react';
import "./App.css";
function App() {
// API That I Used: https://rapidapi.com/apidojo/api/imdb8
const url = 'https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr';
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': 'VITE_RAPID_API_KEY',
'X-RapidAPI-Host': 'imdb8.p.rapidapi.com'
}
};
useEffect(() => {
const fetchData = async () => { // <- async function
try {
const response = await fetch(url, options);
const result = await response.json();
console.log(result);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
return (
<>
<div className="flex justify-center items-center h-screen w-screen">
<h1 className="text-7xl">Rapid API</h1>
</div>
</>
);
}
export default App;
5. How to Hide Your API Keys SAFELY in React
I. Create an Environment File( .env
). Then, Save API Key on .env
You can create an .env
file in the application’s root directory that contains key/value pairs defining the project’s required environment variables. The dotenv library reads this .env file and appends it to process.env.
- For Vite React app
- For react-create-app
How to hide API key on Vite? - Env Variables
If you’re using Vite, you can access environment variables in your project using import.meta.env
Vite has a special handling for environment variables. If you want to expose environment variables to your Vite application, they need to be prefixed with VITE_
- Create a new file named
.env
in the root of your project. - In your new
.env
file, add a new key=value pair. For security reasons, you must prepend your key withVITE_
, for exampleVITE_API_KEY=abcdefg123456789
- Access it in your code like this:
"X-RapidAPI-Key": import.meta.env.VITE_RAPID_API_KEY
- Restart your server development server. In order for React to find and register your newly created environment variable you must restart your server. Do this every time you add or change a variable.
Remember, you should not commit your .env file to the version control system. It’s a good practice to create a .env.example file with all the environment variables used in the application, without the values.
Next steps:
- Check if the environment variable is correctly set in your .env file.
- Make sure to restart your development server after setting the new variables.
- Try to log the environment variable to see if it’s correctly loaded.
How to hide API key on React create app
How do I create an .env file for a React-create-app?
Here is a simple way to use environment variables in your react-create-app
project, follow these steps:
- Create a new file named
.env
in the root of your project. - In your new
.env
file, add a new key=value pair. For security reasons, you must prepend your key withREACT_APP
, for exampleREACT_APP_API_KEY=abcdefg123456789
- Access it in your code like this:
"X-RapidAPI-Key": process.env.REACT_APP_RAPID_API_KEY
- Restart your server development server. In order for React to find and register your newly created environment variable you must restart your server. Do this every time you add or change a variable.
- Your new variables will now be available throughout your React app via the global
process.env
object. In our case, we could get our API key usingprocess.env.REACT_APP_API_KEY
.
Additinal notes:
- Since we commonly store secrets in
.env
you probably want to add it to.gitignore
. - You don’t need to install the
dotenv
package or anything else for this to work.
How to hide API key on Nextjs
To hide your API key in a Next.js project, you should use environment variables. Here’s how you can do it:
- Create a
.env.local
file in the root of your project if it doesn’t exist already. - Add your API key to this file like so:
NEXT_PUBLIC_RAPID_API_KEY=your_api_key_here
. TheNEXT_PUBLIC_
prefix is necessary if you want to access this variable in the browser. If it’s server-side only, you can omit this prefix. - Now you can access this variable in your code using
process.env.NEXT_PUBLIC_RAPID_API_KEY
for browser-accessible variables, orprocess.env.RAPID_API_KEY
for server-side only variables. - Make sure to add
.env.local
to your.gitignore
file to prevent it from being tracked by Git.
Here’s the code:
1
2
// Accessing the API key in your code
const apiKey = process.env.NEXT_PUBLIC_RAPID_API_KEY;
Remember to replace your_api_key_here
with your actual API key. Also, don’t forget to restart your development server after setting the environment variables.
For your next steps, you might want to:
- Use the API key in your application
- Test that the API key is working correctly
- Make sure the
.env.local
file is ignored by Git
II. Create a Backend to Store your Key
Storing the API key on an .env
file and adding the .env
file to .gitignore
is good practice but not completely safe.
Anyone can inspect your code and get the API key from the browser.
Here is how you can prevent people from stealing your API key.
- Follow this Tutorial from Ania.
A. Create a backend.js
in the root ./
of your project
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const PORT = 8000;
const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv").config();
// run: npm install express cors node-fetch dotenv
const app = express();
// Use dynamic import for 'node-fetch'
let fetch;
import("node-fetch").then((nodeFetch) => {
fetch = nodeFetch;
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Got an Error? Use code from
step F
instead.
B. Install the dependencies: express cors node-fetch dotenv
1
npm install express cors node-fetch dotenv
C. Add a Script on package.json
1
2
"scripts": {
"backend": "nodemon backend.js",
It should look like this…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
"name": "movies",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"backend": "nodemon backend.js", // < -- Backend Script
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"node-fetch": "^3.3.2",
"nodemon": "^3.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@vitejs/plugin-react": "^4.2.0",
"autoprefixer": "^10.4.16",
"eslint": "^8.53.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"vite": "^5.0.0"
}
}
D. Install nodemon
1
npm install nodemon
E. Run the Backend to test it
1
npm run backend
Warning: If you got an error:
require is not defined in ES module scope, you can use import instead. This file is being treated as an ES module because it has a '.js' file extension and 'C:\Users\juanc\Documents\Github\ju\package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extens
F. Fixing Error
The error message indicates that require
is not defined in ES module scope. This is because your project is set to use ES modules due to the “type”: “module” in your package.json
file.
You should change all your require
statements to import
statements. Here’s how you can modify your backend.js
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import express from "express";
import cors from "cors";
import { config as dotenvConfig } from "dotenv";
import nodeFetch from "node-fetch";
const PORT = 8000;
// run: npm install express cors node-fetch dotenv
const app = express();
let fetch = nodeFetch;
dotenvConfig();
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Run the Backend to test it again:
npm run backend
G. Add code to backend.js
file and run npm run backend
1
2
3
app.get("/", (req, res) => {
res.json("Hello World!");
});
backend.js
should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Tutorial: https://www.youtube.com/watch?v=FcwfjMebjTU&t=0s
import express from "express";
import cors from "cors";
import { config as dotenvConfig } from "dotenv";
import nodeFetch from "node-fetch";
const PORT = 8000;
// run: npm install express cors node-fetch dotenv
const app = express();
let fetch = nodeFetch;
dotenvConfig();
app.get("/", (req, res) => {
res.json("Hello World!");
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Go to
http://localhost:8000/
to check if it’s working
H. Move Fetch code from App.js
To backend.js
Moving the fetch code from App.js
to backend.js
is a common practice when dealing with APIs for several reasons:
-
Security: It’s safer to store sensitive data like API keys on the server side. If you make the API request from the client side (like in
App.js
), your API key would be exposed to anyone who views the source code of your website. -
CORS (Cross-Origin Resource Sharing): Some APIs don’t allow requests from certain origins (like from a browser). By making the request from your server, you can avoid these issues.
-
Centralization: By making all API requests from your server, you can centralize your data fetching logic in one place. This makes your code easier to maintain and debug.
In your case, the options
object contains your API key, so it’s safer to keep this on the server side. Your server can make the request to the external API, then send the response data back to your client-side React app.
backend.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Tutorial: https://www.youtube.com/watch?v=FcwfjMebjTU&t=0s
import express from "express";
import cors from "cors";
import { config as dotenvConfig } from "dotenv";
import nodeFetch from "node-fetch";
const PORT = 8000;
// run: npm install express cors node-fetch dotenv
const app = express();
let fetch = nodeFetch;
dotenvConfig();
app.get("/", (req, res) => {
res.json("Server running on port 8000! Check port * 8000/backend * for data");
});
app.get("/backend", (req, res) => {
// options is required ~ Rapid API
const options = {
method: "GET",
headers: {
// "X-RapidAPI-Key": import.meta.env.VITE_RAPID_API_KEY, // -->> Default API key from Rapid API. imported for Vite.
"X-RapidAPI-Key": process.env.RAPID_API_KEY, // -->> To access env variables. In Node.js, env variables are accessed via process.env, not import.meta.env.
"X-RapidAPI-Host": "edamam-food-and-grocery-database.p.rapidapi.com",
},
};
const url = 'https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr'; // IMDb API
// async function:
const fetchData = async () => {
try {
const response = await fetch(url, options);
const result = await response.json();
// console.log(result.hints);
console.log(result.hints.food);
// setContainer(result.hints); // setContainer is now an array of objects that contains the data from the API
res.json(result.hints);
} catch (error) {
console.error(error);
}
};
fetchData();
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
App.jsx
Reemplazar el codigo de abajo con el del projecto de movies. Tiene el de food y no movies.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { useEffect, useState } from "react";
import "./App.css";
import Layout from "./Components/Layout";
import Card from "./Components/Card";
function App() {
// API options was here. I moved it to the backend.js file
// First element from useState is the state itself (""). The initial value, in this case an empty string
// Second is the function that will update the state (setEndPoint). The "Changer" function
const [endPoint, setEndPoint] = useState("");
// "Changer" function: it change the state of the endPoint variable by taking the value from the input
const onChangeHandler = (event) => {
setEndPoint(event.target.value);
};
// "Submit" function: it prevent the default behaviour of the form. It won't refresh the page
const onSubmitHandler = (event) => {
event.preventDefault();
console.log("submit");
};
// container is an empty array. setContainer is the function that will update the state of the container
const [container, setContainer] = useState([]);
useEffect(() => {
// url was here. I moved it to the backend.js file
// fetchData function was here. I moved it to the backend.js file
const url = "http://localhost:8000/backend";
// async function:
const fetchData = async () => {
try {
const response = await fetch(url);
const result = await response.json();
// console.log(result.hints);
console.log(result.hints.food);
setContainer(result.hints); // setContainer is now an array of objects that contains the data from the API
} catch (error) {
console.error(error);
}
};
fetchData();
}, [endPoint]);
return (
<>
<Layout>
<div className="flex flex-col items-center justify-center pb-2">
<div className="text-center">
<h1 className="text-4xl md:text-6xl font-bold mb-4">Food API</h1>
<p className="text-xl md:text-2xl p-2">
The best food API for your app, website or recipe using Edamam
Food and Grocery Database
</p>
<p className="text-xs md:text-md py-5 text-gray-400 w-80 md:w-fit">
Food and Grocery Database API: using Rapid API, React, Vite and
Tailwind CSS
</p>
</div>
<div className="grid gap-4 grid-row justify-center sm:grid-cols-2 md:grid-cols-3 w-full max-w-screen-sm md:max-w-screen-md lg:max-w-screen-lg xl:max-w-screen-xl">
{/* {container.map((item) => { */}
{/* return ( */}
{/* <div> */}
{/* <p>{item.image}</p> */}
{/* <img src={item.image} /> */}
{/* </div> */}
{/* ); */}
{/* })} */}
{/* Card */}
{container.map((item) => (
<Card key={item.id} data={item} />
))}
</div>
</div>
</Layout>
</>
);
}
export default App;
- Check that everything is working:
Run npm run backend
You might have to run npm run dev
to see project on localhost:5173
, backend server on localhost:8000
and the API data on localhost:8000/backend
Got a CORS error?
I. Fix CORS error by using CORS package
Error:
Access to fetch at 'http://localhost:8000/backend' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled
Add CORS app.use(cors());
to backend.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Tutorial: https://www.youtube.com/watch?v=FcwfjMebjTU&t=0s
import express from "express";
import cors from "cors";
import { config as dotenvConfig } from "dotenv";
import nodeFetch from "node-fetch";
const PORT = 8000;
// run: npm install express cors node-fetch dotenv
const app = express();
app.use(cors());
let fetch = nodeFetch;
dotenvConfig();
app.get("/", (req, res) => {
res.json("Server running on port 8000! Check port * 8000/backend * for data");
});
app.get("/backend", (req, res) => {
// options is required ~ Rapid API
const options = {
method: "GET",
headers: {
// "X-RapidAPI-Key": import.meta.env.VITE_RAPID_API_KEY, // -->> Default API key from Rapid API. imported for Vite.
"X-RapidAPI-Key": process.env.RAPID_API_KEY, // -->> To access env variables. In Node.js, env variables are accessed via process.env, not import.meta.env.
"X-RapidAPI-Host": "edamam-food-and-grocery-database.p.rapidapi.com",
},
};
const url = 'https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr'; // IMDb API
// async function:
const fetchData = async () => {
try {
const response = await fetch(url, options);
const result = await response.json();
// console.log(result.hints);
console.log(result.hints.food);
// setContainer(result.hints); // setContainer is now an array of objects that contains the data from the API
res.json(result.hints);
} catch (error) {
console.error(error);
}
};
fetchData();
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
J.
K.
6. Style App.js
using Tailwind CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import React, { useEffect } from "react";
import "./App.css";
function App() {
const url = "https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr";
const options = {
method: "GET",
headers: {
"X-RapidAPI-Key": "VITE_RAPID_API_KEY",
"X-RapidAPI-Host": "imdb8.p.rapidapi.com",
},
};
useEffect(() => {
// async function:
const fetchData = async () => {
try {
const response = await fetch(url, options);
const result = await response.json();
console.log(result);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
return (
<>
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
<div className="text-center">
<h1 className="text-4xl md:text-6xl font-bold mb-4">Rapid API</h1>
</div>
<form className="w-full max-w-md">
<input
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
type="text"
placeholder="Search for a movie..."
value={endPoint}
/>
<button
className="mt-4 bg-blue-500 hover:bg-blue-700 transition duration-300 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full"
type="submit"
>
Search
</button>
</form>
</div>
</>
);
}
export default App;
7. Create useState Hooks
Modify the App.js
file. Read the comments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import React, { useEffect, useState } from "react";
import "./App.css";
function App() {
const url = "https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr";
const options = {
method: "GET",
headers: {
"X-RapidAPI-Key": "VITE_RAPID_API_KEY",
"X-RapidAPI-Host": "imdb8.p.rapidapi.com",
},
};
// First element from useState is the state itself (""). The initial value, in this case an empty string
// Second is the function that will update the state (setEndPoint). The "Changer" function
const [endPoint, setEndPoint] = useState("");
// "Changer" function: it change the state of the endPoint variable by taking the value from the input
const onChangeHandler = (event) => {
setEndPoint(event.target.value);
};
// "Submit" function: it prevent the default behaviour of the form. It won't refresh the page
const onSubmitHandler = (event) => {
event.preventDefault();
console.log("submit");
};
// container is an empty array. setContainer is the function that will update the state of the container
const [container, setContainer] = useState([]);
useEffect(() => {
// async function:
const fetchData = async () => {
try {
const response = await fetch(url, options);
const result = await response.json();
// console.log(result); console.log(result.d);
setContainer(result.d); // setContainer is now an array of objects that contains the data from the API
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
return (
<>
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
<div className="text-center">
<h1 className="text-4xl md:text-6xl font-bold mb-4">Rapid API</h1>
</div>
<form className="w-full max-w-md" onSubmit={onSubmitHandler}>
<input
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
type="text"
placeholder="Search for a movie..."
value={endPoint}
onChange={onChangeHandler}
/>
<button
className="mt-4 bg-blue-500 hover:bg-blue-700 transition duration-300 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline w-full"
type="submit"
>
Search
</button>
</form>
</div>
</>
);
}
export default App;
8. Search for Movies
I. Modify the URL
In the API’s URL, replace the information after the q=
for +${endPoint}
in other words:
1
2
3
4
5
// change:
const url = "https://imdb8.p.rapidapi.com/auto-complete?q=game%20of%20thr";
// for:
const url = `https://imdb8.p.rapidapi.com/auto-complete?q=+${endPoint}`;
I also had to organize the code by moving the use states to the top since its trying to use variables that havent been declared and it was giving me an error (Uncaught ReferenceError: Cannot access ‘endPoint’ before initialization at App).
Note: The error message is indicating that you’re trying to access the endPoint variable before it’s been initialized. This is happening because you’re using endPoint in the url constant declaration, which is above the useState hook where endPoint is initialized.
II. Move the URL inside the useEffect
This way, the url is updated every time endPoint changes.
The App.js
should look like this:
1
9. Display or Render data from the API
Modify the App.js
1
10. Render Data when clicking Submit
The app has an issue, it is rendering everytime you type a letter in the input. Instead. We want to render when clicking on Search button.
1
Deployment
There are multiple ways to deploy a React app in just minutes. Here is an article that explains 8 different ways to Deploy a React App.
- From a Github Repo
- From a new project on your machine
License 📜
Distributed under the MIT License. See LICENSE.txt
for more information.
Projects 🚀
Courses & Certifications
For more information regarding my completed courses and certificates, please click on:
Acknowledgments 📚
Resources list that I find helpful and would like to give credit to.