- Lab
- Core Tech

Guided: Implementing an API Gateway in Node.js
In this hands-on lab, you'll learn to implement an API Gateway using Node.js and Express. You'll set up routing of requests to downstream services, transform requests before sending them to a service, and aggregate responses across a set of multiple service. Additionally you will implement rate limiting and authentication across microservices. By the end, you'll have a working API Gateway that implements key concepts of this architectural pattern.

Path Info
Table of Contents
-
Challenge
Adding Routing And Proxying
Introduction to Implementing Routing and Proxying Logic in the Node.js API Gateway
In this first step of building an API Gateway using Node.js and Express, we will focus on implementing the routing and proxying logic. This functionality enables the API Gateway to forward incoming requests to the appropriate downstream services and return the responses back to the clients.
Project Structure Overview:
gateway.js
: The main file of our API Gateway, containing the Express server setup, routing logic, and middleware configuration. This file will be the focal point for implementing the routing and proxying logic.
info> If you get stuck along the way, a solution for each task is included in the
solutions
folder within your filetree.Implementing Routing and Proxying Logic
Your task is to implement the routing and proxying logic inside the predefined route handler for
/api/:service
ingateway.js
. This involves extracting the service parameter from the request URL, constructing the appropriate URL for the downstream service, making an HTTP request to the service usingaxios
, and sending the response back to the client.Method Design:
-
Define Route Handler:
- Use the
app.get()
method to define a route handler for the/api/:service
endpoint. - The route handler should be an asynchronous function (using
async/await
) withreq
andres
parameters.
- Use the
-
Extract Service Parameter:
- Inside the route handler function, extract the service parameter from the request URL using
req.params.service
. - Store the extracted value in a variable named
serviceName
.
- Inside the route handler function, extract the service parameter from the request URL using
-
Construct Service URL:
- Create a variable named
serviceUrl
to store the URL of the downstream service. - Use a template literal to construct the URL in the format
http://localhost:3001/${serviceName}
- Create a variable named
-
Make HTTP Request:
- Use a
try-catch
block to handle the HTTP request and any potential errors. - Inside the
try
block, useaxios.get()
with theawait
keyword to make an asynchronous HTTP GET request toserviceUrl
. - If the request is successful, the response will be stored in a variable named
response
. - Use
res.send()
to send the response data (response.data
) back to the client.
- Use a
-
Error Handling:
- Inside the
catch
block, handle any errors that occur during the HTTP request. - Set the response status code to 500 using
res.status(500)
. - Use
res.send()
to send an error message back to the client, indicating that an error occurred while proxying the request.
- Inside the
-
Challenge
Adding Request Transformation Middleware
Introduction to Implementing Request Transformation in the API Gateway
In this step, you will enhance the API Gateway's functionality by implementing request transformations within the provided
transformRequest
middleware function. This process involves modifying incoming requests by adding custom headers and query parameters before they are forwarded to the downstream services.Implementing Request Transformation Logic
Your task is to complete the implementation of the
transformRequest
middleware function ingateway.js
. This function should modify incoming HTTP requests by adding a custom header and a query parameter. Additionally, you need to ensure that this middleware is applied to the/api/:service
route.Method Design:
-
Complete the Middleware Function:
- Locate the
transformRequest
function ingateway.js
. - Add a custom header named
X-Custom-Header
with the valueHello from API Gateway
to thereq.headers
object. - Add a query parameter named
apiKey
with the valueyour-api-key
to thereq.query
object.
- Locate the
-
Apply the Middleware:
- Ensure that the
transformRequest
middleware is applied to the/api/:service
route by passing it as an argument toapp.get()
. - The middleware should be applied before the request is proxied to the downstream service.
- Ensure that the
-
-
Challenge
Adding Response Aggregation
Introduction to Implementing Response Aggregation in the API Gateway
For this next step, you will enhance the API Gateway to aggregate responses from two distinct services. By completing this task, you will create a single endpoint that consolidates data from multiple sources, simplifying client-side interactions.
Implementing Response Aggregation Logic
Your task is to implement the response aggregation logic within the
/aggregate
endpoint's route handler ingateway.js
. This involves making concurrent requests to two service URLs, aggregating the responses into a single object, and sending the aggregated response back to the client.Method Design:
-
Endpoint Configuration:
- Use the existing
app.get()
setup for the/aggregate
route.
- Use the existing
-
Initialization of Service URLs:
- Within the route handler, define
service1Url
with the valuehttp://localhost:3001/service1
andservice2Url
with the valuehttp://localhost:3002/service2
- Within the route handler, define
-
Concurrent Requests Setup:
- Inside a try block, use
Promise.all()
to make concurrent HTTP GET requests toservice1Url
andservice2Url
usingaxios.get()
. - Assign the result to a constant named
responses
.
- Inside a try block, use
-
Aggregation of Responses:
- Construct an object named
aggregatedResponse
. - Assign
responses[0].data
toaggregatedResponse.service1
andresponses[1].data
toaggregatedResponse.service2
.
- Construct an object named
-
Successful Response Handling:
- Send the
aggregatedResponse
back to the client usingres.json()
.
- Send the
-
Error Management:
- Implement a catch block to handle any errors that occur during the request or aggregation process.
- Use
console.error()
to log the error details. - Respond to the client with a 500 internal server error using
res.status(500).send()
.
-
-
Challenge
Adding Rate Limiting
Rate limiting is crucial for protecting your API Gateway from excessive usage and ensuring fair access to resources. In this task, you will implement rate limiting using the express-rate-limit middleware, which allows you to define rate limiting rules based on the number of requests per IP address within a specified time window.
Implementing Rate Limiting Logic in
gateway.js
Your task is to implement rate limiting within your
gateway.js
file by incorporating theexpress-rate-limit
middleware. You will configure the middleware to allow a maximum of 100 requests per 15 minutes for each IP address and apply it globally to protect all routes.Method Design:
-
Import Rate Limiting Middleware:
- At the top of
gateway.js
, import theexpress-rate-limit
package.
- At the top of
-
Define Rate Limiting Configuration:
- After importing the necessary modules and initializing the Express app, define a constant variable named
apiLimiter
to store the rate limiting configuration. - Assign the rate limiting middleware to
apiLimiter
with the following options:- Set
windowMs
to 15 * 60 * 1000 (15 minutes in milliseconds). - Set
max
to 100 (maximum number of requests per IP within the time window). - Set
standardHeaders
to true (include rate limit information in response headers). - Set
legacyHeaders
to false (disable legacy rate limit headers).
- Set
- After importing the necessary modules and initializing the Express app, define a constant variable named
-
Apply Rate Limiting Middleware:
- Immediately after defining
apiLimiter
, apply it globally to all routes usingapp.use(apiLimiter)
- Immediately after defining
-
-
Challenge
Adding Authentication
Introduction to Implementing Authentication in the API Gateway
In this step, we will focus on implementing basic authentication within the API Gateway. Authentication is a crucial security measure that ensures only authorized users can access protected resources. By adding authentication, you can control who can make requests to your API Gateway and the underlying services.
Implementing Authentication Logic
Your task is to implement basic authentication using the
express-basic-auth
middleware within the API Gateway. This will demonstrate how the API Gateway can secure the routes and protect the backend services by requiring users to provide valid credentials.Method Design:
-
Install Authentication Middleware:
- Ensure you have the
express-basic-auth
package installed in your project. If not, install it using npm or yarn.
- Ensure you have the
-
Define Authentication Middleware:
- Create a constant variable named
authMiddleware
using thebasicAuth
function fromexpress-basic-auth
. This middleware will handle authentication for incoming requests.
- Create a constant variable named
-
Define Authentication Credentials:
- Within the
basicAuth
configuration object, create an object namedusers
that holds the valid username and password combinations for basic authentication. For example:{ admin: 'password' }
.
- Within the
-
Apply Authentication Middleware:
- Apply the
authMiddleware
to the routes you want to protect. For instance, you can apply it to specific routes by adding it as a middleware function before the route handler.
- Apply the
-
Handle Unauthorized Access:
- If a user fails to provide valid credentials, the middleware will automatically challenge them for authentication. You can customize the response message if desired.
-
-
Challenge
Conclusion
Congratulations on successfully completing the API Gateway Implementation Lab!
Throughout this lab, you've made substantial progress in developing a comprehensive API Gateway using Node.js and Express. This gateway serves as a critical component in managing the flow of data between clients and multiple backend services, enhancing both security and efficiency.
Summary of Your Achievements:
-
API Gateway Pattern: You've explored the API Gateway pattern extensively, learning how it integrates into microservice architectures to provide a unified entry point for various services.
-
Routing and Proxying: You've successfully set up routing configurations that direct requests to the correct downstream services, along with proxying logic that ensures these requests are handled appropriately.
-
Request Transformation: By modifying requests as they pass through your gateway, you've ensured that each one is tailored to the needs of the downstream services it interacts with.
-
Response Aggregation: You've implemented logic to aggregate responses from multiple services, simplifying client-side interactions by providing a single, cohesive response.
-
Rate Limiting and Authentication: You've added security layers by implementing rate limiting to protect your services from overuse and authentication to ensure that only authorized users can access your API Gateway.
Interacting with Your API Gateway:
Feel free to test and interact with your API Gateway by starting the server with
node gateway.js
and visiting the endpoints you've configured. For example, you can:- Add new routes to handle different types of requests.
- Adjust the rate limiting settings to see how they affect incoming traffic.
- Enhance security measures by refining the authentication process.
Further Development:
Your API Gateway is now set up to handle basic tasks, but there's room for further enhancement. Consider integrating more advanced security features, such as OAuth, or adding logging and monitoring capabilities to gain insights into traffic patterns and potential security threats.
Further Learning Resources:
To continue improving your skills in Node.js, Express, and general backend development, consider exploring additional courses on Pluralsight. Delve deeper into areas like advanced routing techniques, security enhancements, and performance optimization to build more robust and scalable applications.
-
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.