API Gateway Domains Across Services

Link to chapter - https://serverless-stack.com/chapters/api-gateway-domains-across-services.html

Hi! I’m trying to implement this architecture on the project created during parts one and two. I have added the functions (create, get, list, delete, and update) to the notes service, deployed everything except the user service because the instructions indicated that the service only existed for the point of the tutorial. I hooked the endpoints up to the frontend running locally and was able sign up as a user but I when I try to add a note I get a 502 error. Any idea why that might be? I have cors set to true in my notes service serverless.yml file for all of my added functions.

Okay I figured it out. I had neglected to install the node modules needed for my functions import statements and it was throwing an error at the api gateway.

The chapters on debugging serverless API issues and API Gateway and Lambda logs were what saved me.

Hopefully that helps someone in the future. :v:

1 Like

Glad you figured it out!

1 Like

Hey!
I was finishing the section dealing with the mono repo - and I don’t know if this on purpose - yet I can’t find the API Gateway error-behavior for the 4XX and 5XX (which was called api-gateway-errors.yml in both sections 1 and 2) responses.

The missing code would be

Resources:
  GatewayResponseDefault4XX:
    Type: 'AWS::ApiGateway::GatewayResponse'
    Properties:
      ResponseParameters:
         gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
         gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
      ResponseType: DEFAULT_4XX
      RestApiId:
        Ref: 'ApiGatewayRestApi'
  GatewayResponseDefault5XX:
    Type: 'AWS::ApiGateway::GatewayResponse'
    Properties:
      ResponseParameters:
         gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
         gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
      ResponseType: DEFAULT_5XX
      RestApiId:
        Ref: 'ApiGatewayRestApi'

Or am I missing something here?

Other “issue” that I’m facing is finding a way to create the API Gateway as a separate service, so I don’t chain the dependency graph of services on a AWS Lambda function - to effectively splitting concerns. When I try to create a service only for API Gateway, I always get The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [ApiGatewayRestApi] in the Resources block of the template. Do you guys know if there is a way to do this?

Thanks in advance!

Hmm I’m not totally clear on your first issue? Are you looking for where the snippet came from?

For the second issue. Serverless Framework treats Lambda and its API endpoints together. So I’m not sure if it makes sense to split API Gateway separately?

About the first issue: I was not clear at all, let me go through it again.

I was implementing your mono-repo (that make cross-references through multiple stacks), and I haven’t found the snippet that I’ve mentioned in the previous comment, the one that specifies default responses for our RestAPI. What I mean with “I haven’t found” is that it does not exist in the mono-repo approach, but exists in the first part of the tutorial. I’ve been able to implement it myself, but I was wondering if this was done on purpose?

About the second issue: I’ve actually grasped the concept of the RestAPI that the serverless framework does behind the scenes, so what I was trying to achieve is just “manually” creating a RestAPI, which doesn’t make much sense given the fact that serverless framework creates on in our stack whenever we have at least a function declared inside it. You’re correct, it makes no sense splitting it.

Thanks for the response.

Yeah so the mono-repo GitHub repo that we have is very barebones, just to display the concept of having multiple services. That’s the reason we left out some of those details.

We are going to update it soon to have a more usable template that people can use.

1 Like

Does the strategy outlined in this chapter work for API Gateways new(er) HTTP APIs? My application is using HTTP APIs, and I haven’t had any luck getting this chapter to work. The first problem I see is how the serverless.yml for the notes endpoint outputs the framework generated ApiGatewayRestApi value, which only exists if I have REST API endpoints (which I do not). Is there an analogous HTTP ApI value I should be referencing?

I’m out of my depths with Cloudformation, so I’m not even sure I’m asking the right questions! Any guidance would be appreciated.

I haven’t tried it yet but from what I’ve read, I think HTTP APIs are different. And you can’t use them together with API Gateway.

I’ve got HTTP APIs working in my Serverless app, based on the support provided by the framework. How do you mean “you can’t use them with API Gateway”?

In this chapter of the tutorial, we create REST API endpoint in the notes API and export the ID for other endpoints to use.

- Outputs:
ApiGatewayRestApiId:
  Value:
    Ref: ApiGatewayRestApi
  Export:
    Name: ${self:custom.stage}-ExtApiGatewayRestApiId

ApiGatewayRestApiRootResourceId:
  Value:
     Fn::GetAtt:
      - ApiGatewayRestApi
      - RootResourceId 
  Export:
    Name: ${self:custom.stage}-ExtApiGatewayRestApiRootResourceId

I’m trying to do the same thing with HTTP APIs. However, I don’t know what values to use to refer to the created HTTP endpoints. In the above example, we do an Fn::Getatt of ApiGatewayRestApi and RootResourceId. I can’t seem to figure out the HTTP API equivalent. The Cloudformation Docs seem to support creating an HTTP API, but I am not sure how this applies to my serverless.yml.

After reading more about the Serverless support for HTTP APIs, it looks like I will need to create an HTTP API Externally, and then import it in my Serverless app via a custom variable. I’m not sure if I’m going down the right path or not.

I ended up solving this problem, so I thought I’d chime in here for anyone else who is going down this path.

There are at least two ways to achieve what I was after:

  1. Using 1 API gateway project (what this chapter advocates) to create an HttpApi endpoint and export the ID for consumption in other serverless.yml files. Serverless allows you to define an HttpApi ID for this purpose (link to docs).
  2. Create multiple API Gateway projects and define a custom domain in API Gateway that routes traffic to each of your independently deployed APIs. In this case, you do not need to export the API ID described in the first option. I used the serverless domain manager plugin to help with this implementation.

I ended up going with option 2, but either option will work. In short, you can use the strategy this chapter outlines with HTTP APIs.

3 Likes

Yup that makes sense. Thanks for sharing. AFAIK, you cannot mix the older API Gateway APIs with the newer HTTP APIs. Is that what you found as well?

1 Like

As soon as I used the serverless domain manager all I get is 403 error in all my services, why is that?

Hmm what do you mean? Can you share more details about your setup?

Does anyone have an example of setting this up on a url pattern like this

/api/v1/lookups
/api/v1/environments
/api/v1/graphs

The end of this chapter talks about two things under billing but does not give an example how to do that

Hmm that setup is what this chapter is going over. It’s creating the following:

/notes
/billing

And it talks about how to set this up. That seems similar to what you are looking for?

I ran into the same problem. I am wondering why you just wouldn’t setup the API in the infrastructure project with the custom domain there, have the infrastructure export the Id and then pick that Id up in the api projects.

1 Like