DEV Community

farzana-juthi for AWS Community Builders

Posted on • Originally published at Medium

How to use a single base URL for multiple services in big serverless applications — SAM, API gateway

A bridge to connect multiple path

When you are working on a big application, you may have to use multiple backend services like authentication, payment, access management, and so on. If your architectural design is based on microservices, then all these services will have their own URL link to connect. But think, what happens when you use those separate links in your frontend code? Then if you want to add one more service to your application, you have to change your frontend routing again. It will complicate your system and add extra hassle.

To solve this problem, you can add an Amazon API gateway proxy which helps you to connect all separate URLs using a single base URL.

Lets think you decide to make an e-commerce application where you will have product service, authentication service, cart management, payment service.

Backend Services:

  1. Product service: https://product-service-url

  2. Authentication service: https://auth-service-url

  3. Cart management: https://cart-service-url

  4. Payment service: https://payment-service-url

Now, you do not need to know or manage multiple URLs. API gateway will create a single base URL like https://single-base-url/prod and it will route other services with proxy. Create methods and resources for each services and create path like /product, /auth, /cart, /payment. When you use /product after base URL, it will route you to product service, same as for other services.

I created a github repo for this. Follow the steps in README section to see how functionality in product services can be used through a single base URL. You can create other services like product service.

Here I describe what does mean each section of template.yaml. To create a proxy for each service you need four section:

i) Serverless application: To check all syntax and properties of AWS::Serverless::Application, please check this link.

  ProductStack:
    Type: AWS::Serverless::Application
    Properties:
      Location: product-stack/template.yaml
      Parameters:
        StageName: !Ref StageName 
Enter fullscreen mode Exit fullscreen mode

Here in this section,

1. ProductStack is logical id of this resource. If you want to create other 
   service you have to give a name of that service. Lets say, you will create 
   an application for auth service, you can name it Authstack. 
2. Location: It will indicate the nested application code path. 
   You will give the location of your code.
3. Parameters: If you want to pass any parameters to your cloudformation 
   parameter, then you can pass it here. Here, StageName used for making 
   different state of your project like developement, tesing, production etc. 
   You can pass more parameteres through this section to your nested stack.
Enter fullscreen mode Exit fullscreen mode

ii) API gateway resource for path: To check all syntax and properties of AWS::ApiGateway::Resource, check this link.

  ProductStackApiResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt RootDefaultApi.RootResourceId
      RestApiId: !Ref RootDefaultApi
      PathPart: 'product'  
Enter fullscreen mode Exit fullscreen mode

Here in this section,

1. Type:AWS::ApiGateway::Resource mean it will create a resource in an API.
2. ParentId: It will be the parent resource. As you want to use a single URL, 
   this will be that URL's resource ID. You have to use in all your 
   nexted stack to get signle URL.
3. RestApiId: It will be identifier of associated RestApi
4. PathPart: It is the last path segment of this resource. Here use "product" 
   for productStack. You can use your own name for your stack like "auth" for 
   AuthStack
5. So, for your own nested stack, you have to change the value of ParentId,
   RestApiId and PathPart in this section
Enter fullscreen mode Exit fullscreen mode

iii) API gateway resource for proxy: It is same as previous section. Just use proxy as PathPart.

  ProductStackProxyApiResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !Ref ProductStackApiResource
      RestApiId: !Ref RootDefaultApi
      PathPart: '{proxy+}'
Enter fullscreen mode Exit fullscreen mode

Here in this section,

1. Here {proxy+} is used for routing dynamically. Lets say you want to use 
   base_url/product/{id}, base_url/product/users/{id} under same product rest 
   API. This proxy part allows you to make flexible API endpoint.
2. To make your own nested stack, you have to change only these two
   ParentId, RestApiId in this section. Here your nested stack API gateway 
   resource will be ParentId and your base URL resource will be RestApiId.
Enter fullscreen mode Exit fullscreen mode

iv) API gateway method: To check all syntax and property details, check this link.

  ProductStackProxyMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: ANY
      ResourceId: !Ref ProductStackProxyApiResource
      RestApiId: !Ref RootDefaultApi
      AuthorizationType: NONE
      RequestParameters:
        method.request.path.proxy: true
      Integration:
        CacheKeyParameters:
          - 'method.request.path.proxy'
        RequestParameters:
          integration.request.path.proxy: 'method.request.path.proxy'
        IntegrationHttpMethod: ANY
        Type: HTTP_PROXY
        Uri: !Sub "https://${ProductStack.Outputs.ProductStackApiId}.execute-api.${AWS::Region}.amazonaws.com/${StageName}/{proxy}"
        PassthroughBehavior: WHEN_NO_MATCH
        IntegrationResponses:
          - StatusCode: 200
Enter fullscreen mode Exit fullscreen mode

Here in this section,

1. You have to change the value of ResourceId, RestApiId and Uri. Keep all the 
   value as it is.
2. Value of Uri will be made of the output of your nested stack. So make sure 
   that you export those values as output in nested stack. Otherwise you will 
   not get that value in root stack.
Enter fullscreen mode Exit fullscreen mode

I have added my git link in this post and README describes how you can run this project. Hope you enjoy it. If you have any question, ask me.

If you find this post helpful, please follow me to get more tutorials like this.

Top comments (0)