JAVASCRIPT
Node.js Express Server-Side Proxy for External APIs
Create a server-side proxy in Node.js with Express to securely fetch data from external APIs, bypass CORS restrictions, and hide API keys.
const express = require('express');
const axios = require('axios');
const cors = require('cors'); // To handle CORS for our own API
const app = express();
const port = 3001; // Port for our proxy server
// Allow requests from specific origins, or all origins for development
app.use(cors({ origin: 'http://localhost:3000' })); // Example: only allow frontend on port 3000
// app.use(cors()); // Allow all origins (use with caution in production)
// Middleware to parse JSON request bodies
app.use(express.json());
// Our external API key (THIS SHOULD BE IN ENVIRONMENT VARIABLES IN PRODUCTION)
const EXTERNAL_API_KEY = process.env.EXTERNAL_API_KEY || 'YOUR_SUPER_SECRET_EXTERNAL_API_KEY';
const EXTERNAL_API_BASE_URL = 'https://api.example.com'; // Replace with your target API base URL
/**
* Proxies a GET request to an external API.
* @param {string} externalPath - The path segment for the external API.
* @returns {Function} Express middleware.
*/
app.get('/proxy/external/:externalPath', async (req, res) => {
const { externalPath } = req.params;
const queryParams = req.query; // Forward query parameters
const targetUrl = `${EXTERNAL_API_BASE_URL}/${externalPath}`;
console.log(`Proxying GET request to: ${targetUrl} with query:`, queryParams);
try {
const response = await axios.get(targetUrl, {
params: queryParams,
headers: {
'Authorization': `Bearer ${EXTERNAL_API_KEY}`, // Add API key for external service
// Forward any specific headers if needed, e.g., 'X-Custom-Header': req.headers['x-custom-header']
},
});
// Forward the status and data from the external API to our client
res.status(response.status).json(response.data);
} catch (error) {
console.error(`Error proxying GET to ${targetUrl}:`, error.message);
// Handle different error types (network, API error responses)
if (error.response) {
res.status(error.response.status).json(error.response.data);
} else {
res.status(500).json({ message: 'Internal Server Error during proxy request' });
}
}
});
/**
* Proxies a POST request to an external API.
* This example demonstrates forwarding a request body.
*/
app.post('/proxy/external/:externalPath', async (req, res) => {
const { externalPath } = req.params;
const requestBody = req.body; // The client's request body
const targetUrl = `${EXTERNAL_API_BASE_URL}/${externalPath}`;
console.log(`Proxying POST request to: ${targetUrl} with body:`, requestBody);
try {
const response = await axios.post(targetUrl, requestBody, {
headers: {
'Authorization': `Bearer ${EXTERNAL_API_KEY}`,
'Content-Type': 'application/json', // Assuming JSON body
},
});
res.status(response.status).json(response.data);
} catch (error) {
console.error(`Error proxying POST to ${targetUrl}:`, error.message);
if (error.response) {
res.status(error.response.status).json(error.response.data);
} else {
res.status(500).json({ message: 'Internal Server Error during proxy request' });
}
}
});
app.listen(port, () => {
console.log(`Proxy server listening at http://localhost:${port}`);
console.log('Example usage from client (assuming client is on http://localhost:3000):');
console.log(`fetch('http://localhost:${port}/proxy/external/data?param=value')`);
console.log(`fetch('http://localhost:${port}/proxy/external/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ item: 'new item' }) })`);
});
How it works: This Node.js Express snippet sets up a server-side proxy for external API calls. This is invaluable for several reasons: it bypasses browser CORS restrictions, allows you to hide sensitive API keys from the client by managing them on the server, and provides a single point of control for interacting with third-party services. The proxy receives requests from your frontend, forwards them to the external API with necessary authentication (like an API key), and then returns the external API's response back to your frontend. It demonstrates handling both GET and POST requests, forwarding query parameters and request bodies respectively.