Table of Contents:
- Introduction
- Using A One API Portal
- Th end
Introduction:
In my last blog post, we walked through the process of building a straightforward application with the Serverless Framework and NestJS. Today, we’re going to take a step further. Our primary focus will be on having all apps under a single AWS API Gateway, as opposed to each having its separate gateway.
A one API Portal:
As we said each of 3 apps was related to its own API portal what i first did is to go to the serverless documentation and I found this post talking about how to create a configuration for an API portal and expose it as an output for the other apps and serverless files to use.
So here is what I did, first I created a configuration folder configand added a new serverless file to it so my files structure now looks like this
apps
users
src
app.controller.ts
app.module.ts
app.service.ts
main.ts
serverless.yaml
tsconfig.app.json
items
src
app.controller.ts
app.module.ts
app.service.ts
main.ts
serverless.yaml
tsconfig.app.json
config
serverless.yaml
nest-cli.json
serverless-compose.yaml
package.json
tsconfig.json
.eslintrc.js
I also added this config folder to the serverless-compose.yaml
services:
users:
path: apps/users
dependsOn: config
items:
path: apps/items
dependsOn: config
config:
path: config
After done with the file configuration part i moved back to my config/serverless.yaml file and added the following code to it
service: config
provider:
name: aws
runtime: nodejs16.x
stage: dev
region: eu-west-3
resources:
Resources:
MyApiGW:
Type: AWS::ApiGateway::RestApi
Properties:
Name: MyApiGW
Outputs:
apiGatewayRestApiId:
Value:
Ref: MyApiGW
Export:
Name: MyApiGateway-restApiId
apiGatewayRestApiRootResourceId:
Value:
Fn::GetAtt:
- MyApiGW
- RootResourceId
Export:
Name: MyApiGateway-rootResourceId
Now let’s break down this file and explain each line of it:
- service: config: Here, we're simply naming our service "config".
- provider:: This section gives the details about our cloud service provider. We specify we're using Amazon Web Services (name: aws), with Node.js 16.x as the runtime environment (runtime: nodejs16.x). We also denote we're working in the development stage (stage: dev) in the region 'eu-west-3' (region: eu-west-3).
- resources:: In this block, we define the AWS resources used in our service.
- MyApiGW:: We name our API Gateway "MyApiGW".
- Type: AWS::ApiGateway::RestApi: We specify we're creating a RESTful API using AWS's API Gateway.
- Properties: Name: MyApiGW: We set the name of the API Gateway under properties.
- Outputs:: This part is where we define the output values from our serverless service. These are useful for cross-stack resource sharing or for sharing references with other services.
- apiGatewayRestApiId:: We're exporting the ID of the API Gateway here. The value is a reference to the API Gateway we defined earlier (Ref: MyApiGW). The exported output is named "MyApiGateway-restApiId" (Export: Name: MyApiGateway-restApiId).
- apiGatewayRestApiRootResourceId:: Similarly, we're exporting the Root Resource ID of the API Gateway. The value is the "RootResourceId" attribute from the API Gateway (Fn::GetAtt: - MyApiGW - RootResourceId). The exported output is named "MyApiGateway-rootResourceId" (Export: Name: MyApiGateway-rootResourceId).
For more details about this make sure to check :
- Serverless API Gateway V1 documentation
- There is also another way to achieve the same results by following Serverless API Gateway V2 documentation, API Gateway V2 is faster and cheaper than V1 according to the documentation.
- Also, check this link for a simple explanation.
- And this one contains better documentation.
We have now successfully set up our configuration file. The next step involves instructing our two applications users and items to use the API Gateway that we’ve established in our configuration folder. Let’s proceed with that
Now that we’re all set with the configuration, let’s navigate to users/serverless.yaml and items/serverless.yaml Within the provider section of these files, we’ll add the following lines of code:
# users/serverless.yaml and items/serverless.yaml
provider:
....
apiGateway:
restApiId:
'Fn::ImportValue': MyApiGateway-restApiId
restApiRootResourceId:
'Fn::ImportValue': MyApiGateway-rootResourceId
Now let’s explain the simple changes that we added to the two files :
- provider.apiGateway.restApiId - This tells Serverless Framework to use an existing AWS API Gateway, instead of creating a new one for this service. The existing API Gateway's ID is provided by importing the value from CloudFormation's output named "MyApiGateway-restApiId". This is useful when you want to manage the API Gateway separately from the Serverless application or share it among multiple Serverless applications.
- provider.apiGateway.restApiRootResourceId - Similarly, this tells Serverless Framework to use an existing root resource in the AWS API Gateway, instead of creating a new one. The existing root resource's ID is provided by importing the value from CloudFormation's output named "MyApiGateway-rootResourceId". This is again useful when the root resource is managed separately or shared among multiple Serverless applications.
Note: Fn::ImportValue is a CloudFormation intrinsic function used to import values exported by other stacks in the same AWS account and region. This allows for cross-stack references, sharing resources and values among different CloudFormation stacks, which can be useful for managing larger architectures or when it is beneficial to have separate stacks for different concerns.
For a more comprehensive understanding of CloudFormation’s intrinsic functions and stacks, I highly recommend diving into the following resources:
now we simply need to run :
npm run deploy
Which was already added to our package.json file in the root directory of the app.
"scripts": {
"build:users": "nest build --tsc users",
"build:items": "nest build --tsc items",
"build:all": "npm run build:users && npm run build:items",
...
"deploy": "npm install && npm run build:all && npx serverless deploy",
...
},
Following these steps, you can navigate to your AWS console and locate API Gateway. There, you will discover a single, centralized API Gateway managing all of your application links. Its interface should resemble the screenshot provided below.
An illustrative screenshot showcasing a custom API Gateway, constructed with the method followed in this blog post, utilizing NestJS and the Serverless Framework.
So instead of seeing the links in the dashboard, you will see an items and books links.
In summary, here’s a concise roadmap to consolidate our multiple apps under a single API gateway:
- Construct a configuration file containing the YAML setup for the API gateway, and ensure it exports the apiGatewayRestApiId and apiGatewayRestApiRootResourceId.
- Incorporate these two exported values into the provider section of all our application-specific serverless.yaml files.
- Deploy the app and validate our unified API gateway via the AWS console.
The end
I hope this post has offered some insight into my learning journey and the steps I’ve taken to create an app using NestJS and Serverless Framework. If you’ve made it this far, I want to extend my sincere gratitude for your time and interest.
Your feedback means a lot to me. If you have any suggestions or simply want to share your own experiences, I invite you to leave a comment or get in touch.
Stay tuned for my upcoming post, where i will explore adding authentication to the application. Thank you.
Top comments (0)