Front-End Web & Mobile

Introducing Custom Domain Names for AWS AppSync APIs

AWS AppSync is a managed serverless GraphQL service that makes it easy to create GraphQL APIs. You can use AppSync to securely access, manipulate, and combine data from one or more data sources in a single API call. Developers use AppSync to build scalable applications for a wide range of use cases, such as real-time collaboration, real-time chat application, offline application sync, unified data access, and unified microservices access. In this article, we describe a new AppSync feature – custom domain names that let customers use their own domain names with their AppSync APIs.

When you create a GraphQL API using AppSync, two endpoints with different host names are provisioned for your API:

  • A GraphQL endpoint – https://example123.appsync-api.us-east-1.amazonaws.com/graphql
  • A real-time endpoint – wss://example123.appsync-realtime-api.us-east-1.amazonaws.com/graphql

Applications can connect to the AWS AppSync GraphQL endpoint (https://) using any HTTP client for queries and mutations, and to the AWS AppSync real-time endpoint (wss://) using any WebSocket client for subscriptions.

With custom domain names, you can now configure a single memorable domain name that works for both the GraphQL endpoint and real-time endpoint of an AppSync API. You can use a domain name that you own and associate it with any AppSync API in your AWS account. Moreover, you can change your API association with a custom domain name at any time. For example, with a custom domain name api.example.com, the GraphQL endpoint and real-time endpoint can be invoked using these URLs:

  • AppSync GraphQL endpoint – https://api.example.com/graphql
  • AppSync real-time endpoint – wss://api.example.com/graphql/realtime

Customers can now brand their API endpoints to make it easy for API consumers to discover while leveraging all of the existing AppSync functionalities. Customers can align with any organizational security guidelines using recognizable API endpoints, and they can eliminate the overhead of configuring two different host names for the AppSync API endpoints. In addition, customers can change the AppSync API associated with a custom domain without changing their APIs by simply swapping out the AppSync API associated with the custom domain name.

Setting up the Custom Domain Name on AWS AppSync API

In this section, I will demonstrate how to set up a custom domain name for an AppSync API. I will create a custom domain name, associate it to an AppSync API, and invoke the API endpoints using the custom domain URLs.

Step 1 – Register a domain name

You must have a registered internet domain name to set up custom domain names for your AppSync APIs. If needed, you can register an internet domain by using Amazon Route 53 or a third-party domain registrar of your choice. The custom domain name for an AppSync API can be a subdomain or the root domain (also known as “zone apex”) of a registered internet domain. Here, I will use the domain name codeforevery.com, which was created using a third-party domain registrar with DNS provided by Amazon Route 53. The following diagram shows the public hosted zone in Route 53 for the domain name.

The Route53 hosted zone details for codeforevery.com showing the records

Step 2 – Create a certificate for the domain name

You can request AWS Certificate Manager (ACM) to generate a new certificate or import one into ACM that was issued by a third-party certificate authority. The import must be done in ACM in the us-east-1 Region (US East (N. Virginia)) following the instructions here.

For codeforevery.com a new wildcard certificate was requested in ACM, as shown in the following diagram.

The AWS Certificate Manager wild card certificate for codeforevery.com

Step 3 – Create an AppSync custom domain name and associate to an AppSync API

  1. On the AppSync console, navigate to the left menu and select “Custom Domain Names”. Then, select the button “Create domain name”.

The landing page for creating AppSync Custom Domain Names

  1. Provide the custom domain name for the AppSync API and the ACM certificate for the domain name. Then, select the button “Create”.

To create a custom domain, you will need to provide the details Domain Name, ACM Certificate and Description

  1. AppSync creates the AppSync Domain Name and shows the AppSync GraphQL endpoint and real-time endpoint. At this point, no AppSync API has been associated with the newly created custom domain name. Note: When you create a custom domain name in AppSync, the AppSync service sets up a CloudFront distribution, owned and managed by AWS, and provides the CloudFront distribution domain name as the AppSync Domain Name. You must then set up a DNS record to map your custom domain name to the AppSync Domain Name which I will carry out in a later step.

The details of the newly created custom domain name for api.codeforevery.com

  1. Associate the custom domain name with an AppSync API by selecting the button “Associate an API” or “Update” to proceed with the association. Here, we select an API called “My Event App” that was generated from the Event App sample project available on the AppSync console.

Associating the newly created custom domain with AppSync API

  1. AppSync initiates the association of the AppSync API to the custom domain. This process takes a couple of minutes to complete. When completed, the association connection’s status is marked as “Associated”.

AppSync custom domain associated with an AppSync API

Step 4 – Update your DNS records to route traffic to the AppSync Domain Name

For Route 53, create a new record in the hosted zone to direct API call to the custom domain name (e.g., api.codeforevery.com) to the AppSync Domain name (e.g., xxxxxxxxxxxxxx.cloudfront.net).

Creating a Route53 CNAME record for api.codeforevery.com to map the newly created custom domain name to the cloudfront distribution endpoint.

Invoking AppSync API with Custom Domain name

The APIs can be invoked using any command line tool of your choice. Here, we use curl to send queries and mutations, and we use wscat to set up a subscription on the real-time endpoint.

Mutation – createEvent Request

$ curl -s -XPOST https://api.codeforevery.com/graphql \
-H "Content-Type:application/graphql" \
-H "x-api-key:da2-xxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{"query": "mutation CreateEvent ($name: String!,$when: String!, $where: String!,$description: String!) {createEvent(description: $description, name: $name, when: $when, where: $where) {description id name when where}}","variables":"{\"name\":\"Birthday\",\"when\":\"Next Week\",\"where\":\"Spain\",\"description\":\"My Birthday Party\"}"}'

Mutation – createEvent Response

{
  "data": {
    "createEvent": {
      "description": "My Birthday Party",
      "id": "069e69f5-b60f-4be5-9d56-2da8f93baf83",
      "name": "Birthday",
      "when": "Next Week",
      "where": "Spain"
    }
  }
}

Query – getEvent Request

$ curl -s -XPOST https://api.codeforevery.com/graphql \
-H "Content-Type:application/graphql" \
-H "x-api-key:da2-xxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{"query": "query GetEvent($id: ID!){getEvent(id: $id){description id name when where}}","variables":"{\"id\":\"069e69f5-b60f-4be5-9d56-2da8f93baf83\"}"}

Query – getEvent Response

{
  "data": {
    "getEvent": {
      "description": "My Birthday Party",
      "id": "069e69f5-b60f-4be5-9d56-2da8f93baf83",
      "name": "Birthday",
      "when": "Next Week",
      "where": "Spain"
    }
  }
}

Subscription to “commentOnEvent” Mutation

We establish a subscription using wscat. For details on setting up a subscription, see Building a Real-time WebSocket Client.

$ header=`echo '{"host":"api.codeforevery.com","x-api-key":"da2-xxxxxxxxxxxxxxxxxxxxxxxxxx"}' | base64`
$ wscat -p 13 -s graphql-ws -c  "wss://api.codeforevery.com/graphql/realtime?header=$header&payload=e30="
Connected (press CTRL+C to quit)
> {"type": "connection_init"}
< {"type":"connection_ack","payload":{"connectionTimeoutMs":300000}}
< {"type":"ka"}
> {"id":"f7a49717-4b2d-401e-abe7-986c84f5c844-local-1","payload":{"data":"{\"query\":\"subscription MySubscription($eventId: String!) {\\n subscribeToEventComments(eventId: $eventId) {\\n commentId \\n content \\n createdAt\\n }\\n}\\n\",\"variables\":{\"eventId\":\"069e69f5-b60f-4be5-9d56-2da8f93baf83\"}}","extensions":{"authorization":{"x-api-key":"da2-mdfe7ibtwrfkbekibfg6w5267e","host":"api.codeforevery.com"}}},"type":"start"}
< {"id":"f7a49717-4b2d-401e-abe7-986c84f5c844-local-1","type":"start_ack"

From another terminal, we execute the “commentOnEvent” Mutation.

$ curl -s -XPOST https://api.codeforevery.com/graphql \
-H "Content-Type:application/graphql" \
-H "x-api-key:da2-xxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d '{"query": "mutation CommentOnEvent($content: String!, $createdAt: String!, $eventId: ID!) {commentOnEvent(content: $content, createdAt: $createdAt, eventId: $eventId) {commentId content createdAt eventId }}","variables":"{\"content\":\"Great event enjoyed it\",\"createdAt\":\"Today\",\"eventId\":\"069e69f5-b60f-4be5-9d56-2da8f93baf83\"}"}' 
{"data":{"commentOnEvent":{"commentId":"66ec903b-72e3-4664-8bd1-6a243f172644","content":"Great event enjoyed it","createdAt":"Today","eventId":"069e69f5-b60f-4be5-9d56-2da8f93baf83"}}}

The subscription is trigged, and the message notification appears in the established websocket.

< {"id":"f7a49717-4b2d-401e-abe7-986c84f5c844-local-1","type":"data","payload":{"data":{"subscribeToEventComments":{"commentId":"66ec903b-72e3-4664-8bd1-6a243f172644","content":"Great event enjoyed it","createdAt":"Today"}}}}

Building a web or mobile application

You can configure the AWS Amplify library in your application to use custom domain names with the Amplify API client and Amplify DataStore. Simply configure the custom domain name as part of the AppSync configuration parameters as shown in the following. Refer to the documentation here for more details.

const myAppConfig = {
    // ...
    'aws_appsync_graphqlEndpoint': 'https://<custom-domain-name>/graphql',
    'aws_appsync_region': '<region>',
    'aws_appsync_authenticationType': 'API_KEY',
    'aws_appsync_apiKey': '<api-key>',
    // ...
}; 
Amplify.configure(myAppConfig);

Changing the API association

You can change the API association of your custom domain at any time. In this way, you can execute blue/green deployments of your AppSync API without having to update your deployed application. From the command line, using the AWS CLI:

$ aws appsync associate-api --domain-name api.codeforevery.com --api-id <api-id>

Important things to know

  • AppSync API custom domain supports Transport Layer Security (TLS) protocol version 1.2 and above (TLS 1.2 and TLS 1.3).
  • The default GraphQL endpoint and real-time endpoint of your AppSync API can still be used to invoke the API after configuring custom domain name.
  • To create a wildcard custom domain name, specify (*) as the subdomain of your custom domain name which will represent all possible subdomains of a root domain. For example, using *.codeforevery.com as the AppSync custom domain results in subdomains, such as a.codeforevery.comb.codeforevery.com, and c.codeforevery.com, which all route to the same domain.
  • You can find out the exact value of the custom domain used to access your AppSync API in the context variable $context.request.domainName.
  • There can be only one instance of an AppSync custom domain name (e.g., api.codeforevery.com) on the AWS platform (across regions and across AWS Accounts) at any given time. Setting up AppSync custom domain names maps the domain name to an Amazon Cloudfront distribution.
  • To set up the custom domain name or to update its certificate, you must have a permission to update CloudFront distributions and describe the ACM certificate that you plan to use. Refer to the documentation here for the IAM policy.

Get started today!

Support for custom domain on AWS AppSync is generally available in all AWS regions where AWS AppSync is available today. Learn more about this new capability by reading the documentation here.

About the author

Ozioma Uzoegwu

Ozioma is a Senior Solutions Architect at Amazon Web Services. In his role, he helps customers of all sizes to transform and modernise on AWS cloud platform by providing architectural guidance and best practices. Ozioma has many years of experience with web development, architecture, cloud and IT management. Prior to joining AWS, Ozioma worked with an AWS Advanced Consulting Partner as the Lead Architect for the AWS Practice. He is passionate about software development with a keen interest in building modern applications using serverless technologies.