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/ios/.
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, the included Amplify components allow Amplify to provide auth tokens and signing logic for the corresponding Authorizers.
Install the AWS AppSync Apollo Extensions library
Add AWS AppSync Apollo Extensions into your project using Swift Package Manager.
Enter its GitHub URL (https://github.com/aws-amplify/aws-appsync-apollo-extensions-swift
), select Up to Next Major Version and click Add Package
- Select the following libraries:
- AWSAppSyncApolloExtensions
Connecting to AWS AppSync with Apollo client
AWS AppSync supports the following authorization modes:
API_KEY
import AWSAppSyncApolloExtensions
let authorizer = APIKeyAuthorizer(apiKey: "[API_KEY]")let interceptor = AppSyncInterceptor(authorizer)
AMAZON_COGNITO_USER_POOLS
If you are using Amplify Auth, you can create a method that retrieves the Cognito access token
import Amplify
func getUserPoolAccessToken() async throws -> String { let authSession = try await Amplify.Auth.fetchAuthSession() if let result = (authSession as? AuthCognitoTokensProvider)?.getCognitoTokens() { switch result { case .success(let tokens): return tokens.accessToken case .failure(let error): throw error } } throw AuthError.unknown("Did not receive a valid response from fetchAuthSession for get token.")}
Then create the AuthTokenAuthorizer with this method.
import AWSAppSyncApolloExtensions
let authorizer = AuthTokenAuthorizer(fetchLatestAuthToken: getUserPoolAccessToken)let interceptor = AppSyncInterceptor(authorizer)
AWS_IAM
If you are using Amplify Auth, you can use the following method for AWS_IAM auth
import AWSCognitoAuthPluginimport AWSAppSyncApolloExtensions
let authorizer = IAMAuthorizer( signRequest: AWSCognitoAuthPlugin.createAppSyncSigner( region: "[REGION]"))
Connecting Amplify Data to Apollo client
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:
- Enter its GitHub URL (
https://github.com/aws-amplify/amplify-swift
), select Up to Next Major Version and click Add Package - Select the following libraries:
- AWSPluginsCore
- Drag and drop the
amplify_outputs.json
file into your Xcode project. - Initialize the configuration with
try AWSAppSyncConfiguration(with: .amplifyOutputs)
The resulting configuration object will have the endpoint
, region
, and optional apiKey.
The following example shows reading the amplify_outputs.json
file from the main bundle to instantiate the configuration and uses it to configure the Apollo client for API_Key authorization.
import Apolloimport ApolloAPIimport AWSPluginsCoreimport AWSAppSyncApolloExtensions
func createApolloClient() throws -> ApolloClient { let store = ApolloStore(cache: InMemoryNormalizedCache()) // 1. Read AWS AppSync API configuration from `amplify_outputs.json` let configuration = try AWSAppSyncConfiguration(with: .amplifyOutputs) // 2. Use `configuration.apiKey` with APIKeyAuthorizer let authorizer = APIKeyAuthorizer(apiKey: configuration.apiKey ?? "") let interceptor = AppSyncInterceptor(authorizer) let interceptorProvider = DefaultPrependInterceptorProvider(interceptor: interceptor, store: store) // 3. Use `configuration.endpoint` with RequestChainNetworkTransport let transport = RequestChainNetworkTransport(interceptorProvider: interceptorProvider, endpointURL: configuration.endpoint)
return ApolloClient(networkTransport: transport, store: store)}
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.
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 Code Generation documentation.
You can alternatively download the introspection schema using the fetch-schema
command with the amplify-ios-cli
tool.
Generating Queries, Mutations, and Subscriptions for Apollo client
- 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.
Connecting to AWS AppSync real-time endpoint
The following example shows how you can create an Apollo client that allows performing GraphQL subscription operations with AWS AppSync.
import Apolloimport ApolloAPIimport ApolloWebSocketimport AWSPluginsCoreimport AWSAppSyncApolloExtensions
func createApolloClient() throws -> ApolloClient { let store = ApolloStore(cache: InMemoryNormalizedCache()) let configuration = try AWSAppSyncConfiguration(with: .amplifyOutputs) // 1. Create your authorizer let authorizer = /* your Authorizer */ let interceptor = AppSyncInterceptor(authorizer)
let interceptorProvider = DefaultPrependInterceptorProvider(interceptor: interceptor, store: store) let transport = RequestChainNetworkTransport(interceptorProvider: interceptorProvider, endpointURL: configuration.endpoint)
// 2. Create the AWS AppSync compatible websocket client let websocket = AppSyncWebSocketClient(endpointURL: configuration.endpoint, authorizer: authorizer) // 3. Add it to the WebSocketTransport let webSocketTransport = WebSocketTransport(websocket: websocket) // 4. Create a SplitNetworkTransport let splitTransport = SplitNetworkTransport( uploadingNetworkTransport: transport, webSocketNetworkTransport: webSocketTransport ) // 5. Pass the SplitNetworkTransport to the ApolloClient return ApolloClient(networkTransport: splitTransport, store: store)}