JAVASCRIPT
Node.js Secure External API Proxy
Create a Node.js (Express) server-side proxy to securely interact with external APIs, hide API keys, perform data transformations, and manage server-to-server communication.
const express = require('express');
const axios = require('axios'); // For making HTTP requests to external APIs
const cors = require('cors'); // To allow cross-origin requests from frontend
const app = express();
const port = process.env.PORT || 3000;
// --- Configuration ---
// IMPORTANT: Store sensitive API keys in environment variables, not directly in code.
const EXTERNAL_API_BASE_URL = process.env.EXTERNAL_API_BASE_URL || 'https://api.example.com';
const EXTERNAL_API_KEY = process.env.EXTERNAL_API_KEY || 'YOUR_SECURE_API_KEY'; // Example: for a third-party service
// Middleware to enable CORS for frontend applications
app.use(cors());
app.use(express.json()); // For parsing application/json
// Example proxy endpoint: Fetch data from an external API
app.get('/api/proxy/external-data', async (req, res) => {
try {
// Construct the URL for the external API
const externalUrl = `${EXTERNAL_API_BASE_URL}/v1/data`;
// Make the request to the external API from the Node.js server
const response = await axios.get(externalUrl, {
headers: {
'Authorization': `Bearer ${EXTERNAL_API_KEY}`, // Add API key securely from server
'User-Agent': 'Node.js Proxy Server' // Identify your proxy
// Any other headers required by the external API
},
params: req.query // Pass query parameters from client to external API
});
// Optionally, transform the data before sending it to the client
const transformedData = {
status: 'success',
timestamp: new Date().toISOString(),
// Include only necessary data, filter sensitive info
data: response.data.results || response.data
};
res.json(transformedData);
} catch (error) {
console.error('Error proxying external API request:', error.message);
// Better error handling in production: don't expose raw external API errors
if (error.response) {
res.status(error.response.status).json({
error: 'Failed to fetch external data',
details: error.response.data
});
} else {
res.status(500).json({ error: 'Internal server error' });
}
}
});
// Example proxy for a POST request
app.post('/api/proxy/external-resource', async (req, res) => {
try {
const externalUrl = `${EXTERNAL_API_BASE_URL}/v1/resources`;
const payload = req.body; // Data sent by the client
const response = await axios.post(externalUrl, payload, {
headers: {
'Authorization': `Bearer ${EXTERNAL_API_KEY}`,
'Content-Type': 'application/json'
}
});
res.status(response.status).json(response.data);
} catch (error) {
console.error('Error proxying external POST request:', error.message);
if (error.response) {
res.status(error.response.status).json({
error: 'Failed to create external resource',
details: error.response.data
});
} else {
res.status(500).json({ error: 'Internal server error' });
}
}
});
app.listen(port, () => {
console.log(`Proxy server listening at http://localhost:${port}`);
console.log(`External API Base URL: ${EXTERNAL_API_BASE_URL}`);
});
// To run:
// 1. npm install express axios cors
// 2. Create a .env file:
// EXTERNAL_API_BASE_URL=https://jsonplaceholder.typicode.com
// EXTERNAL_API_KEY=your_secret_key_here
// 3. node your_proxy_file.js
//
// Test from client:
// fetch('http://localhost:3000/api/proxy/external-data?userId=1')
// .then(res => res.json())
// .then(data => console.log(data));
How it works: This Node.js (Express) snippet sets up a server-side proxy for making calls to external APIs. This pattern is crucial for web developers because it allows hiding sensitive API keys from client-side code, preventing CORS issues, and enabling data transformation or aggregation before sending data to the client. Using a proxy enhances security, allows for server-side caching, and gives more control over API interactions, especially with third-party services. Environment variables are used for secure storage of API keys.