F5 NGINX API Gateway: Simplify Response Manipulation
In the fast-evolving world of digital applications, APIs are the unsung heroes driving seamless connectivity. But what if you could elevate your APIs to deliver more value—without overhauling your backend? With the F5 NGINX API Gateway, powered by the lightweight NGINX Javascript NJS) module, you can dynamically manipulate API responses, streamline operations, and delight your users. In this article, we'll walk you through a hands-on example of response manipulation using F5 NGINX API Gateway, highlight the power of batching API requests with F5 NGINX Plus, and share best practices to ensure success. Ready to transform your API strategy? Let's get started!
A Hands-On Example: Boosting API Responses with F5 NGINX API Gateway
Let's consider a practical scenario. You manage a simple API server that returns numeric values, but your business team wants to increment each response value by 10 for a promotional campaign. Instead of modifying the backend, you can use F5 NGINX API Gateway to handle this at the gateway layer, saving time and keeping your backend lean.
Step 1: The Backend API
Let’s start by creating a simple Node.js Express application (app.js) to serve as our backend API. For this example, we’ll assume Node.js is already installed on an Ubuntu 24.04 server. In my setup, the backend API runs on the IP address 10.1.1.5, which we’ll reference later in the nginx.conf file for proxying requests. Here’s how to get the backend up and running:
// Import the Express framework to create a web server
const express = require('express');
// Initialize an Express application instance
const app = express();
// Add middleware to log incoming requests for debugging purposes
app.use((req, res, next) => {
// Log the request method, URL, and headers in a formatted string
console.log(`Received request: ${req.method} ${req.url} Headers: ${JSON.stringify(req.headers)}`);
// Call the next middleware or route handler in the chain
next();
});
// Define a GET route for '/api/v1/1' that returns a JSON response with value 100
app.get('/api/v1/1', (req, res) => res.json({ value: 100 }));
// Define a GET route for '/api/v1/2' that returns a JSON response with value 200
app.get('/api/v1/2', (req, res) => res.json({ value: 200 }));
// Define a GET route for '/api/v1/3' that returns a JSON response with value 300
app.get('/api/v1/3', (req, res) => res.json({ value: 300 }));
// Define a GET route for '/api/v1' that returns a JSON response with value 10
app.get('/api/v1', (req, res) => res.json({ value: 10 }));
// Start the Express server on port 3050, listening on all network interfaces ('0.0.0.0')
app.listen(3050, '0.0.0.0', () => console.log('API server running on port 3050'));
This server returns JSON responses like {"value": 100}. Now, let's enhance these responses using NGINX.
Step 2: NGINX Configuration
Next, configure NGINX (nginx.conf) to proxy requests to the backend and manipulate the responses using the NJS module:
# Load the njs module to enable dynamic scripting capabilities
load_module /usr/lib/nginx/modules/ngx_http_js_module.so;
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Import the njs script 'manipulate.js' and alias it as 'manipulate'
js_import manipulate from /etc/nginx/njs/manipulate.js;
server {
listen 80;
location /api/ {
# Proxy requests to the backend server running on 10.1.1.5:3050
proxy_pass http://10.1.1.5:3050;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
# Apply the njs body filter to manipulate the response before sending to the client
js_body_filter manipulate.manipulateBodyFilter;
}
}
}
The js_body_filter directive is where the magic happens—it calls the NJS script to modify the response.
Step 3: The NJS Script for Response Manipulation
Here’s the NJS script (manipulate.js) that adds 10 to the value field in each response:
// Define the body filter function to manipulate API responses
function manipulateBodyFilter(r, data, flags) {
try {
// Check if there is no data in the response chunk
if (!data) {
// If no data, send an empty buffer to the client and exit
r.sendBuffer("", flags);
return;
}
// Log the received data chunk for debugging purposes
r.log("Received chunk: " + data);
// Store the data chunk in a variable (body filter processes data in chunks)
let body = data;
// Parse the data as JSON to work with the response object
let parsedBody = JSON.parse(body);
// Validate that the 'value' field exists and is a number
if (parsedBody.value === undefined || typeof parsedBody.value !== 'number') {
// Log an error if the response format is invalid
r.error("Invalid response format: 'value' missing or not a number");
// Send an error message to the client and exit
r.sendBuffer("Invalid response format", flags);
return;
}
// Increment the 'value' field by 10 to modify the response
parsedBody.value = parsedBody.value + 10;
// Convert the modified object back to JSON and send it to the client
r.sendBuffer(JSON.stringify(parsedBody), flags);
} catch (e) {
// Log any errors that occur during processing (e.g., JSON parsing failure)
r.error("NJS Error in body filter: " + e.message);
// Send an error message to the client with the error details
r.sendBuffer("Internal Server Error: " + e.message, flags);
}
}
// Export the manipulateBodyFilter function for use in NGINX configuration
export default { manipulateBodyFilter };
How It Works
- A client sends a request to /api/v1/1 via NGINX.
- NGINX proxies the request to the backend, which responds with {"value": 100}.
- The js_body_filter intercepts the response, adds 10 to the value, and sends {"value": 110} to the client.
Test it with curl http://<nginx-ip>/api/v1/1 and see the modified response in action. It’s a seamless way to enhance your APIs without backend changes!
Why This Matters
Using NGINX API Gateway for response manipulation saves development time, reduces backend complexity, and allows dynamic adjustments. Whether adding fields, transforming data, or enforcing policies, NGINX gives you the flexibility to adapt quickly.
Batching API Requests: Efficiency with F5 NGINX Plus
For efficiency, you should take a quick look at the F5 blog post “Batching API Requests with NGINX Plus and the JavaScript Module”. This article showcases how F5 NGINX Plus can batch multiple API calls into a single HTTP request, reducing latency and server load.
Using NJS, you can create a custom request handler to aggregate API calls server-side (Aggregation means combining multiple API requests into one on the server side). The article provides a practical example of implementing request batching with F5 NGINX Plus. This technique optimises resource usage and speeds up client response times.
Why It’s a Game-Changer
- Lower Latency: Fewer round trips to the backend.
- Scalability: Offload processing to NGINX Plus.
- Customization: Tailor batching logic with JavaScript.
Combine this with response manipulation, and you’ve got an API Gateway that’s both intelligent and efficient.
Best Practices for NGINX API Gateway Success
To ensure your NGINX API Gateway deployment shines, here are some best practices from F5’s “Deploying NGINX as an API Gateway” whitepaper
- Optimize Buffers: Configure proxy_buffer_size and proxy_buffers to handle larger responses smoothly.
- Set Timeouts: Use proxy_connect_timeout and proxy_read_timeout to prevent hanging requests.
- Handle Errors Gracefully: As shown in manipulate.js, always include error handling and logging.
- Prioritize Security: Implement authentication and rate limiting with NGINX Plus to safeguard your APIs.
- Start Small, Scale Up: Begin with simple logic, then expand as needed.
Explore More with NJS Examples
Looking for inspiration? The NGINX njs Examples on GitHub offers a treasure trove of use cases, from authentication to content rewriting. It’s the perfect resource to fuel your NGINX API Gateway journey.
Why Choose NGINX with F5?
NGINX, backed by F5’s world-class expertise, is more than a tool—it’s a strategic advantage. Whether using open-source NGINX or unlocking advanced features with F5 NGINX Plus, you get unmatched performance, flexibility, and support. Ready to make your APIs a competitive edge? Contact F5 today to see how NGINX can accelerate your business.