0% found this document useful (0 votes)
179 views

An Introduction To API Gateway in NestJS With Microservices and Rest APIs - Part 01 - by Marcos Henrique Da Silva - Medium

The document introduces building an API gateway for NestJS applications using NestJS and microservices, outlining how to scaffold a project with three services (API gateway, users, and tasks) using NX, create REST APIs for each service, and configure the API gateway to proxy requests to the other services using http-proxy-middleware.

Uploaded by

trungtrungkang
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
179 views

An Introduction To API Gateway in NestJS With Microservices and Rest APIs - Part 01 - by Marcos Henrique Da Silva - Medium

The document introduces building an API gateway for NestJS applications using NestJS and microservices, outlining how to scaffold a project with three services (API gateway, users, and tasks) using NX, create REST APIs for each service, and configure the API gateway to proxy requests to the other services using http-proxy-middleware.

Uploaded by

trungtrungkang
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

An introduction to API Gateway in NestJS with

Microservices and Rest APIs — part 01


A practical guide on creating an API Gateway for your NestJS apps!

Photo by Mo Eid: https://www.pexels.com/photo/person-in-black-shirt-walking-on-sand-8347501/

Hello and welcome! In this article we are going to talk about API Gateway, microservices,
REST APIs (again) and all with NestJS

I was a bit reluctant to write about this topic, specially because when talking about API
Gateway and Microservices a lot of people deviates on how you should architect “in the
correct way” but still there are no much content about it using NestJS as well as NestJS
documentation for who is not used to Microservices might be complicated.

That said, my disclaimer here is that… Don’t take what I am writing today as set on stone
but… think that is one approach that might fit your needs and please feel free to
change/adapt/evolve what I am writing here for your personal needs.
Before we start…
This article might be slightly more advanced for who never worked with NestJS. If you are
new to NestJS and REST APIs I would recommend to read my previous article first:

Creating a REST API series with NestJS — Part 01 — Scaffolding and


basic CLI usage
Welcome back! In the mini series of article I am going to guide you on how
to built a REST API using NestJS framework
makinhs.medium.com

Or, if you would like to check about GraphQL, you can go here:

GraphQL Back-End in Node.js Made Easy with NestJS


In this article, I will show you how to start a GraphQL back-end project in a
very, very, very easy way…using NestJS!
javascript.plainenglish.io

Last, but not least… there’s also a very nice article about Kafka, microservices and NestJS
here:

An Introduction to Kafka with TypeScript using NestJS


A practical way to introduce you into Kafka, KafkaJS, NestJS micro-
services with real examples.
javascript.plainenglish.io

That said, basic concepts you might need to follow up this article are:

Basic Typescript knowledge

NestJS basics (Should be nice to know the basics of building a REST API)
In this part 01 we are going to scaffold the project, create 2 isolated REST APIs and
configure the API Gateway to proxy those 2 isolated REST APIs

What we will build


The articles series aims to create an API gateway that will be creating 2 microservices with
simple functionality:

users: basic CRUD operation which will have their own REST API

tasks: a beginning of what could be a task manager which also will have their own REST
API

For authentication and to maintain things isolated, I will implement the authentication on
the API Gateway level, which for creating an JWT it will communicate with the users
microservice.

To make it easy to follow as a source code for future study, we are also going to use all those
projects in a monorepo with nx

Disclaimer: in this approach the microservices are exposing their own REST endpoints
but keep in mind that following this approach then you should care about not exposing
their endpoints in a public way. This is easily manageable with Kubernetes and/or any
Cloud infra like AWS, Azure

Scaffolding the project


In a terminal, start your project with NX:

npx create-nx-workspace nest-medium --preset=nest

It will ask for an application name that in our case is the main one and we are calling it  api-
gateway
creating a project with nx

NX is a build system that allows monorepo approach. For this project we are not going
deeper on this but just organising all the projects in one single repo that I can share in the
end of the article ;)

The result is a project with apps/api-gateway which is your desirable API Gateway that we
are going to code on. The default port is 3333.

To test is everything is ok just run  npm start  in your terminal. You should be able to get the
classic “Hello world” in your root directory.
Now to have the API Gateway working, we still need to have the other microservices in
place. Let’s scaffold them with:

nx g @nrwl/nest:app users

and

nx g @nrwl/nest:app tasks

Once they are done, we will have all the 3 scaffolded projects:

In order to run all the projects at the same time, I am creating a .env file to each project
containing the PORT value with the following: 3331, 3332, 3333

in api-gateway:

PORT=3330

in users
PORT=3331

in tasks

PORT=3332

With that made… we can finally run the all the three applications at the same time with just
one command:

nx run-many --target=serve

the result is something like:

> NX Running target serve for 3 project(s):

- api-gateway
- tasks
- users

—————————————————————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————

> nx run api-gateway:serve

> nx run tasks:serve

> nx run users:serveMapped

... removed some lines here


{/api, GET} route +3ms
[Nest] 38912 - 09/29/2022, 8:37:25 PM LOG 🚀 Application is running
on: http://localhost:3332/api
[Nest] 38913 - 09/29/2022, 8:37:25 PM LOG [NestApplication] Nest
application successfully started +2ms
[Nest] 38914 - 09/29/2022, 8:37:25 PM LOG [RoutesResolver]
AppController {/api}: +10ms
[Nest] 38913 - 09/29/2022, 8:37:25 PM LOG 🚀 Application is running
on: http://localhost:3331/api
[Nest] 38914 - 09/29/2022, 8:37:25 PM LOG [RouterExplorer] Mapped
{/api, GET} route +3ms
[Nest] 38914 - 09/29/2022, 8:37:25 PM LOG [NestApplication] Nest
application successfully started +2ms
[Nest] 38914 - 09/29/2022, 8:37:25 PM LOG 🚀 Application is running
on: http://localhost:3330/api

In the users project we are going to scaffold the users module with:

nest g resource users

The same in tasks but for tasks module with:

nest g resource tasks

An example result is:

~/projects/nest-medium/apps/tasks main +3 !3 ?14 ❯ nest g resource tasks


Node 16.17.0 20:45:10
? What transport layer do you use? REST API
? Would you like to generate CRUD entry points? Yes
CREATE src/tasks/tasks.controller.spec.ts (566 bytes)
CREATE src/tasks/tasks.controller.ts (894 bytes)
CREATE src/tasks/tasks.module.ts (247 bytes)
CREATE src/tasks/tasks.service.spec.ts (453 bytes)
CREATE src/tasks/tasks.service.ts (609 bytes)
CREATE src/tasks/dto/create-task.dto.ts (30 bytes)
CREATE src/tasks/dto/update-task.dto.ts (169 bytes)
CREATE src/tasks/entities/task.entity.ts (21 bytes)

A lot of scaffolding here… But it worth it ;)

A problem on NX and Nest CLI is that now you still need to import the Users/Tasks in their
respectives app.module.ts, as well as installing the following dependency:

npm i @nestjs/mapped-types
Now we are good to test like a curl to http://localhost:3331/api/users

~/projects ❯ curl http://localhost:3331/api/users

This action returns all users%

How do we connect this to the API Gateway now? The short answer is: http-proxy-
middleware

Let’s configure this first,

npm i http-proxy-middleware

Now, in the  main.ts  from api-gateway we will import the proxy middleware

import {createProxyMiddleware} from 'http-proxy-middleware';


...
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const globalPrefix = 'api';
app.setGlobalPrefix(globalPrefix);
const port = process.env.PORT || 3333;
const USERS_SERVICE_URL = "http://localhost:3331";
const TASKS_SERVICE_URL = "http://localhost:3332";

// Proxy endpoints
app.use('/api/users', createProxyMiddleware({
target: USERS_SERVICE_URL,
changeOrigin: true,
}));
app.use('/api/tasks', createProxyMiddleware({
target: TASKS_SERVICE_URL,
changeOrigin: true,
}));
await app.listen(port);
Logger.log(
` 🚀Application is running on:
http://localhost:${port}/${globalPrefix}`
);
}
bootstrap();

With that you will have the API Gateway up and running and every time you will hit the
/api/users* or /api/tasks* the correct REST microservice will be proxied properly

Running a curl now in our API Gateway:

~/projects ❯ curl http://localhost:3330/api/users

This action returns all users%

We have everything ready now

Handling Auth
For handling Auth with the http-proxy-middleware we can use their built-in built-in
function onProxyReq:

app.use('/api/users', createProxyMiddleware({
target: USERS_SERVICE_URL,
changeOrigin: true,
onProxyReq: (clientRequest, req) =>{
//some validation goes here
}
}));

Keep in mind that the request will be proxied to the next “server” that most possibly won’t
be in the same local instance.

If you are using JWT and the header Authorisation with  Bearer JWT  then you could have a
service in the API Gateway that confirms that the JWT is valid and then move forward, else
finishing the request/response cycle right away.
By now we scaffolded the monorepo project with NX, created the basics of the API Gateway,
scaffolded 2 REST APIs and slightly tackled the how to manipulate the Authorisation flow.

In the next article we are going to configure the microservice module for users and tasks as
well as finishing some CRUD operations to have a useful project as a guideline. Later on we
are going to actually implement the Auth flow, including permissions.

You can check the full source code for this project in this public branch on Github

If this article was anyhow useful please follow me for more content, give a clap and/or a
comment. That makes me happy to write more ;)

If this kind of article is too simple and you feel yourself prepared to a real adventure,
specially on a remote good paid basis, please try to join Toptal with my
referral link https://topt.al/KncQD8. Toptal is a great community for freelancers and I
will be happy to see you there!

Thanks for reading!

Want a similar approach but focusing on GraphQL API? Check my other article:

An introduction to Apollo Federation in NestJS


A practical guide for using NestJS to create GraphQL apps with Apollo
Federation on top of it
makinhs.medium.com

More articles made by me:

An Introduction to Kafka with TypeScript using NestJS


A practical way to introduce you into Kafka, KafkaJS, NestJS micro-
services with real examples.
javascript.plainenglish.io
5 Reasons to become a Contractor over Employee in Software
Engineering
and 5 reasons why you should not do it as well!
makinhs.medium.com

You might also like