AWS AppSync Apollo Extensions
AWS AppSync Apollo Extensions provide a seamless way to connect to your AWS AppSync backend using Apollo client, an open-source GraphQL client.
To learn more about Apollo, see https://www.apollographql.com/docs/kotlin.
Features
AWS AppSync Apollo Extensions provide AWS AppSync authorizers to be used with the Apollo client to make it simple to apply the correct authorization payloads to your GraphQL operations.
Additionally, we publish an optional Amplify extension that allows Amplify to provide auth tokens and signing logic for the corresponding Authorizers.
Install the AWS AppSync Apollo Extensions library
Add the apollo-appsync-amplify
dependency to your app/build.gradle.kts file.
dependencies { // Connect Apollo to AppSync, delegating some implementation details to Amplify implementation("com.amplifyframework:apollo-appsync-amplify:1.0.0") }
Add the apollo-appsync
dependency to your app/build.gradle.kts file.
dependencies { // Connect Apollo to AppSync without using Amplify implementation("com.amplifyframework:apollo-appsync:1.0.0") }
Connecting to AWS AppSync with Apollo client
Creating the ApolloClient
Before you begin, you will need an Amplify Data backend deploy. To get started, see Set up Data.
Once you have deployed your backend and created the amplify_outputs.json
file, you can use Amplify library to read and retrieve your configuration values with the following steps:
// Use apiKey auth mode, reading configuration from AmplifyOutputsval connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))val apolloClient = ApolloClient.Builder() .appSync(connector.endpoint, connector.apiKeyAuthorizer()) .build()
You can create your Apollo client by using our provided AWS AppSync endpoint and authorizer classes.
val endpoint = AppSyncEndpoint("<your_appsync_endpoint>")// Continue Reading to see more authorizer examplesval authorizer = ApiKeyAuthorizer("[API_KEY]") val apolloClient = ApolloClient.Builder() .appSync(endpoint, authorizer) .build()
Providing AppSync Authorizers
The AWS AppSync Apollo Extensions library provides a number of Authorizer classes to match the various authorization strategies that may be in use in your schema. You should choose the appropriate Authorizer type for your authorization strategy. To read more about the strategies and their corresponding auth modes, see Available authorization strategies.
Some common ones are
publicAPIkey
strategy,apiKey
authMode, APIKeyAuthorizerguest
strategy,identityPool
authMode, IAMAuthorizerowner
strategy,userPool
authMode, AuthTokenAuthorizer
If you define multiple authorization strategies within your schema, you will have to create separate Apollo client instances for each Authorizer that you want to use in your app.
API_KEY
An ApiKeyAuthorizer
can read the API key from amplify_outputs.json
, provide a hardcoded API key, or fetch the API key from some source:
// Using ApolloAmplifyConnector to read API key from amplify_outputs.jsonval connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))val authorizer = connector.apiKeyAuthorizer()// or// Use a hard-coded API keyval authorizer = ApiKeyAuthorizer("[API_KEY]")// or// Fetch the API key from some source. This function may be called many times,// so it should implement appropriate caching internally.val authorizer = ApiKeyAuthorizer { fetchApiKey() }
AMAZON_COGNITO_USER_POOLS
You can use AmplifyApolloConnector
to get an AuthTokenAuthorizer
instance that supplies the token for the current logged-in Amplify user, or implement the token fetching yourself.
// Using ApolloAmplifyConnector to get the authorizer that connects to your // Amplify instanceval connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))val authorizer = connector.authTokenAuthorizer()// or// Using the ApolloAmplifyConnector companion functionval authorizer = AuthTokenAuthorizer { ApolloAmplifyConnector.fetchLatestCognitoAuthToken() }// or// Use your own token fetching. This function may be called many times,// so it should implement appropriate caching internally.val authorizer = AuthTokenAuthorizer { fetchLatestAuthToken()}
You can provide your own custom fetchLatestAuthToken
provider for AWS_LAMBDA and OPENID_CONNECT auth modes.
AWS_IAM
You can use the ApolloAmplifyConnector
to delegate token fetching and request
signing to Amplify.
// Using ApolloAmplifyConnector to get the authorizer that connects to your // Amplify instanceval connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))val authorizer = connector.iamAuthorizer()// or// Using the ApolloAmplifyConnector companion functionval authorizer = IamAuthorizer { ApolloAmplifyConnector.signAppSyncRequest(it, "us-east-1") }
AWS AppSync supports the following authorization modes. Use the corresponding Authorizer that matches the chosen authorization type.
Some common ones are
- API Key Authorization -> APIKeyAuthorizer
- IAM Authorization -> IAMAuthorizer
- Cognito User Pools -> AuthTokenAuthorizer
If you apply multiple authorization directives in your schema, you will have to create separate Apollo client instances for each Authorizer that you want to use in your app.
API_KEY
An ApiKeyAuthorizer
can be used with a hardcoded API key or by fetching the key from some source.:
// Use a hard-coded API keyval authorizer = ApiKeyAuthorizer("[API_KEY]")// or// Fetch the API key from some source. This function may be called many times,// so it should implement appropriate caching internally.val authorizer = ApiKeyAuthorizer { fetchApiKey() }
AMAZON_COGNITO_USER_POOLS
When working directly with AppSync, you must implement the token fetching yourself.
// Use your own token fetching. This function may be called many times,// so it should implement appropriate caching internally.val authorizer = AuthTokenAuthorizer { fetchLatestAuthToken()}
AWS_IAM
When working directly with AppSync, you must implement the request signing yourself.
// Provide an implementation of the signing function. This function should implement the // AWS Sig-v4 signing logic and return the authorization headers containing the token and signature.val authorizer = IamAuthorizer { signRequestAndReturnHeaders(it) }
Downloading the AWS AppSync schema
The schema is used by Apollo’s code generation tool to generate API code that helps you execute GraphQL operations. The following steps integrate your AppSync schema with Apollo's code generation process:
- Navigate to your API on the AWS AppSync console
- On the left side, select Schema
- Select the "Export schema" dropdown and download the
schema.json
file. - Add this file to your project as directed by Apollo documentation
Generating Queries, Mutations, and Subscriptions for Apollo client
Amplify provided .graphql files
- Within your Amplify Gen 2 backend, run:
npx ampx generate graphql-client-code --format graphql-codegen --statement-target graphql --out graphql
- Copy the generated files (
mutations.graphql
,queries.graphql
,subscriptions.graphql
) to your{app}/src/main/graphql
folder as shown in the Apollo documentation
Manual
- Navigate to the Queries tab in your API on the AWS AppSync console. Here, you can test queries, mutations, and subscriptions in the GraphQL playground.
- Enter your GraphQL operation (query, mutation, or subscription) in the editor and select Run to execute it.
- Observe the request and response structure in the results. This gives you insight into the exact call patterns and structure that Apollo will use.
- Copy the GraphQL operation(s) from the playground and pass them to to your
{app}/src/main/graphql
folder as shown in the Apollo documentation
- Navigate to the Queries tab in your API on the AWS AppSync console. Here, you can test queries, mutations, and subscriptions in the GraphQL playground.
- Enter your GraphQL operation (query, mutation, or subscription) in the editor and click Run to execute it.
- Observe the request and response structure in the results. This gives you insight into the exact call patterns and structure that Apollo will use.
- Copy the GraphQL operation from the playground and pass it to Apollo's code generation tool to automatically generate the corresponding API code for your project.
Type Mapping AppSync Scalars
By default, AWS AppSync Scalars will default to the Any
type. You can map these scalars to more explicit types by editing the apollo
block in your app/build.gradle[.kts]
file. In the example below, we are now mapping a few of our AppSync scalar types to String
instead of Any
. Additional improvements could be made by writing custom class adapters to convert date/time scalars into Kotlin date/time class types.
apollo { service("{serviceName}") { packageName.set("{packageName}") mapScalarToKotlinString("AWSDateTime") mapScalarToKotlinString("AWSEmail") }}