DEV Community

Ez Pz Developement
Ez Pz Developement

Posted on • Originally published at ezpzdev.Medium on

Building a Serverless Application with NestJS and the Serverless Framework: API portal

Header image for Building a Serverless Application with NestJS and the Serverless Framework: API portal

Table of Contents:

  1. Introduction
  2. Using A One API Portal
  3. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 :

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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",
  ...
},
Enter fullscreen mode Exit fullscreen mode

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 Image that show how the api portal will look like after folloàwing the required steps
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)