How to configure custom domain names for AppSync

0
picture
Profile picture of Yan Cui Hacker Noon

@the burning monkYan Cui

AWS Serverless Heroes. Independant consultant. Developer Lawyer at Lumigo.

One thing that API Gateway supports, but that you can’t do with AppSync out of the box yet, is custom domain names.

Your brand new AppSync API is available at

XYZ.appsync-api.us-east-1.amazonaws.com/graphql

, but you really want people to use your own domain instead, because

dev.example.com/graphql

is much more memorable and informative.

In this article, let’s take a look at two ways to do this.

I’ve already written five reasons why you should consider AppSync on API Gateway. Read the article here.

1. CloudFront

This is my favorite method. This is easy to install and inexpensive to run.

Assuming your AppSync API resource is called

GraphQlApi

(if you are using the serverless-appsync-plugin with the Serverless framework, then this is the logical identifier that it will use). This is the CloudFormation resource that you must configure to route traffic to the AppSync API.

AppSyncDistribution:
  Type: AWS::CloudFront::Distribution
  Properties:
    DistributionConfig:
      Origins:
        - Id: AppSync
          DomainName:
            Fn::Select:
              - '2'
              - Fn::Split:
                  - "/"
                  - Fn::GetAtt:
                      - GraphQlApi
                      - GraphQLUrl
          CustomOriginConfig:
            HTTPPort: 80
            HTTPSPort: 443
            OriginProtocolPolicy: https-only
            OriginSSLProtocols:
              - TLSv1
              - TLSv1.1
              - TLSv1.2
          OriginPath: ''
      Enabled: true
      HttpVersion: http2
      Comment: CloudFront distribution for the Patient AppSync API
      Aliases:
        -  DOMAIN NAME HERE, e.g. dev.example.com>
      PriceClass: PriceClass_100
      DefaultCacheBehavior:
        AllowedMethods:
          - HEAD
          - OPTIONS
          - GET
          - DELETE
          - POST
          - PUT
          - PATCH
        CachedMethods:
          - HEAD
          - OPTIONS
          - GET
        ForwardedValues:
          QueryString: true
          Headers:
            - x-api-key
            - Authorization
          Cookies:
            Forward: all
        MinTTL: 0
        DefaultTTL: 0
        TargetOriginId: AppSync
        ViewerProtocolPolicy: redirect-to-https
        Compress: true
      CustomErrorResponses: []
      ViewerCertificate:
        AcmCertificateArn:  ARN HERE>
        SslSupportMethod: sni-only

If you are using the Serverless framework, you should also check out the serverless-appsync-cloudfront plugin. It can make things a lot easier for you. However, at the time of writing, it is making assumptions about the logical ID of the AppSync API (it is waiting

GraphQlApi

) as intended for use with the above

serverless-appsync-plugin

.

2. API Gateway

Another way to do this is through API Gateway. You can configure an HTTP proxy that routes traffic to the AppSync API, and then configure a custom domain name in API Gateway.

Compared to using CloudFront, this approach takes more work to configure and results in higher costs and latency (compared to using CloudFront) because every request has to go through API Gateway.

If you are using the Serverless framework, another stumbling block is that you cannot easily declare an API gateway without any Lambda functions. Fortunately, you can work around this problem by bringing the macro from SAM

AWS::Serverless-2016–10–31

in the

serverless.yml

like in this post.

This allows you to configure API Gateway using the AWS :: Serverless :: Api resource type from SAM.

ApiGateway:
  Type: AWS::Serverless::Api
  Properties:
    Name: AppSyncApiProxy
    StageName: dev
    OpenApiVersion: "3.0.1"
    DefinitionBody:
      openapi: "3.0.1"
      paths:
        /{proxy+}:
          "x-amazon-apigateway-any-method":
            consumes:
              - "application/json"
            produces:
              - "application/json"
            parameters:
              - name: proxy
                in: path
                required: true
                type: string
            x-amazon-apigateway-integration:
              uri: 
                Fn::Join:
                  - ''
                  - - 'https://'
                    - Fn::Select:
                        - '2'
                        - Fn::Split:
                            - "/"
                            - Fn::GetAtt:
                                - GraphQlApi
                                - GraphQLUrl
                    - '/{proxy}'
              passthroughBehavior: when_no_match
              httpMethod: ANY
              type: http_proxy                  
              requestParameters:
                integration.request.path.proxy : method.request.path.proxy
    EndpointConfiguration: REGIONAL

ApiGatewayDomainName:
  Type: AWS::ApiGateway::DomainName
  Properties:
    DomainName:  DOMAIN NAME>
    EndpointConfiguration:
      Types:
        - REGIONAL
    RegionalCertificateArn:  ARN HERE>

ApiGatewayBasePathMapping:
  Type: AWS::ApiGateway::BasePathMapping
  DependsOn:
    - ApiGatewayDomainName
  Properties:
    DomainName:  DOMAIN NAME>
    RestApiId: !Ref ApiGateway
    Stage: !Ref ApiGateway.Stage

One thing to note here is that by default SAM creates an API Gateway step called

Stage

. This appears to be a long standing bug with SAM and the workaround is to set

OpenApiVersion

To

3.0.1

.

Route53

As a final step for both of these approaches, you need to set up a Route53 record for them in your hosted zone.

For CloudFront, you need something like this:

picture

For API Gateway, you need to capture the

API Gateway domain name

for the custom domain (in API Gateway) and configure a Route53 record against it.

picture
picture

You can also configure them using CloudFormation.

Summary

With these two approaches, you can create a custom domain name (such as

dev.example.com

) for AppSync. Callers can access your AppSync API through

dev.example.com/graphql

which is much more user-friendly and memorable.

As mentioned above, I prefer the CloudFront approach because it is easier to configure and has negligible overhead.

Previously published on https://theburningmonk.com/2020/09/how-to-set-up-custom-domain-names-for-appsync/

Profile picture of Yan Cui Hacker Noon

Keywords

Join Hacker Midi

Create your free account to unlock your personalized reading experience.

Share.

Leave A Reply