Next.js Tutorial: Creating a Metals Market Data Application with Cacheing
In this tutorial, we will create a Next.js application that fetches market data from an API, caches it locally, and serves it through an API endpoint to keep the secret safe. The cache will refresh every minute, allowing efficient use of the API without excessive calls.
Step 1: Set Up Your Next.js Application
First, make sure you have Node.js installed on your machine. If you haven’t already set up a Next.js application, you can create one using the following command:
npx create-next-app@latest metals-market-app cd metals-market-app
Step 2: Install Axios
We will use Axios to fetch data from the API. Install Axios with the following command:
npm install axios
Step 3: Create the API Route
Next.js allows you to create API routes easily. Create a new directory named api inside the pages directory, and then create a file named metals.js inside the api directory.
mkdir pages/api touch pages/api/metals.js
Step 4: Implement Caching Logic in the API Route
Now, open pages/api/metals.js and implement the logic to fetch and cache the market data.
// pages/api/metals.js
import axios from 'axios';
let cache = null; // Variable to hold cached data
let lastFetched = null; // Variable to track last fetch time
const API_KEY = 'YOUR-API-KEY'; // Replace with your actual API key
const API_URL = 'https://metals.g.apised.com/v1/market-data?symbols=XAU,XAG,XPD,XPT,XCU,NI,ZNC,ALU,LEAD&base_currency=USD';
// Function to fetch data from the API
const fetchMetalsData = async () => {
try {
const response = await axios.get(API_URL, {
headers: {
'x-api-key': API_KEY,
},
});
cache = response.data; // Store response in cache
lastFetched = Date.now(); // Record the fetch time
console.log('Data fetched from API');
} catch (error) {
console.error('Error fetching data:', error.message);
}
};
// Function to check cache validity
const isCacheValid = () => {
if (!cache) return false; // If cache is empty, return false
return (Date.now() - lastFetched) < 60000; // Cache is valid for 60 seconds
};
// API Route to get market data
export default async function handler(req, res) {
if (!isCacheValid()) {
await fetchMetalsData(); // Fetch new data if cache is invalid
}
res.status(200).json(cache); // Return cached data
}
// Start fetching data initially
fetchMetalsData();
setInterval(fetchMetalsData, 60000); // Refresh cache every 60 seconds
Step 5: Create a Page to Display the Data
Next, create a simple page that fetches the cached data from the API route and displays it. Open the pages/index.js file and update it as follows:
// pages/index.js
import { useEffect, useState } from 'react';
export default function Home() {
const [metalsData, setMetalsData] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const fetchMetalsData = async () => {
try {
const response = await fetch('/api/metals');
if (!response.ok) throw new Error('Network response was not ok');
const result = await response.json();
console.log(result.data.rates)
setMetalsData(result.data.rates);
setLoading(false);
} catch (error) {
setError('Failed to fetch data');
setLoading(false);
}
};
useEffect(() => {
fetchMetalsData();
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>{error}</p>;
return (
<div>
<h1>Metals Market Data</h1>
<table>
<thead>
<tr>
<th>Symbol</th>
<th>Open (USD)</th>
<th>High (USD)</th>
<th>Low (USD)</th>
<th>Prev (USD)</th>
<th>current (USD)</th>
</tr>
</thead>
<tbody>
{Object.keys(metalsData).map((metalKey) => {
console.log(metalKey)
return (
<tr key={metalKey}>
<td>{metalKey}</td>
<td>{metalsData[metalKey].open}</td>
<td>{metalsData[metalKey].high}</td>
<td>{metalsData[metalKey].low}</td>
<td>{metalsData[metalKey].prev}</td>
<td>{metalsData[metalKey].current}</td>
</tr>
)
})}
</tbody>
</table>
<style jsx>{`
table {
margin: 20px auto;
border-collapse: collapse;
width: 80%;
}
th, td {
border: 1px solid #ccc;
padding: 10px;
}
th {
background-color: #f2f2f2;
}
`}</style>
</div>
);
}
Step 6: Run Your Next.js Application
Now you can run your Next.js application by executing the following command in your terminal:
npm run dev
Your Next.js application should now be running on http://localhost:3000. You should see a loading message initially, and once the data is fetched from your API route, it will display a table with the symbols and prices of the metals.
Conclusion
Congratulations! You've built a Next.js application that fetches market data from an external API, caches it locally, and serves it through an API endpoint. The cache refreshes every minute, allowing efficient data retrieval without excessive API calls. You can further enhance this application by adding features like error handling, logging, or user-friendly design.