Skip to content

Instantly share code, notes, and snippets.

@stefangomez
Last active July 2, 2019 00:05
Show Gist options
  • Save stefangomez/759777b0640642fa93cb4f9bed026865 to your computer and use it in GitHub Desktop.
Save stefangomez/759777b0640642fa93cb4f9bed026865 to your computer and use it in GitHub Desktop.
amplify/appsync client setup for cognito authed users + unauthed users via api key
import Amplify from "@aws-amplify/core";
import Auth from "@aws-amplify/auth";
import { setContext } from "apollo-link-context";
import { ApolloLink } from "apollo-link";
import { createHttpLink } from "apollo-link-http";
import AWSAppSyncClient, { AUTH_TYPE, createAppSyncLink } from "aws-appsync";
import awsConfig from "../aws-exports";
Amplify.configure({
...awsConfig,
Analytics: { disabled: true }
});
const appsyncClient = new AWSAppSyncClient(awsConfig, {
link: createAppSyncLink({
url: awsConfig.aws_appsync_graphqlEndpoint,
region: awsConfig.aws_appsync_region,
auth: {
type: AUTH_TYPE.API_KEY,
apiKey: awsConfig.aws_appsync_apiKey
},
resultsFetcherLink: ApolloLink.from([
setContext(async (request, previousContext) => {
try {
const session = await Auth.currentSession();
return {
headers: {
...previousContext.headers,
Authorization: session.getIdToken().getJwtToken()
}
};
} catch (e) {
return {
headers: previousContext.headers
};
}
}),
createHttpLink({
uri: awsConfig.aws_appsync_graphqlEndpoint
})
])
})
});
export default appsyncClient;
// manual setup / code mostly borrowed from: https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/203
import ApolloClient from "apollo-client";
import fetch from "isomorphic-fetch";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
import { setContext } from "apollo-link-context";
import { ApolloLink } from "apollo-link";
import { getMainDefinition } from "apollo-utilities";
import { SubscriptionHandshakeLink } from "aws-appsync/lib/link/subscription-handshake-link"; // importing directly so AWS-SDK does not get introduced
import { NonTerminatingHttpLink } from "aws-appsync/lib/link/non-terminating-http-link";
import { onError } from "apollo-link-error";
import Amplify from "@aws-amplify/core";
import Auth from "@aws-amplify/auth";
import aws_config from "../aws-exports";
Amplify.configure({ ...aws_config, Analytics: { disabled: true } });
const createApolloClient = initialState => {
// Allows for custom logic when a GraphQL or network error occurs
const onErrorLink = onError(({ graphQLErrors, networkError, response }) => {
console.log("onErrorLink:onError:graphQLErrors", graphQLErrors);
const allGraphQLErros = [
...(graphQLErrors || []),
...((networkError && networkError.graphQLErrors) || [])
];
if (allGraphQLErros) {
allGraphQLErros.forEach(({ message, locations, path }) => {
const error = new Error(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
);
console.log(error);
});
}
if (networkError)
console.log(new Error(`[Network error]: ${networkError}`));
// response.errors = null;
});
// create authLink (override headers) for Apollo to use:
// - cognito JWT for authenticated users
// - api key auth for unauthenticated users
const apolloAuthLink = setContext(async (_, { headers }) => {
try {
const session = await Auth.currentSession();
return {
headers: {
...headers,
authorization: session.getIdToken().getJwtToken()
}
};
} catch (e) {
return {
headers: {
...headers,
"X-Api-Key": aws_config.aws_appsync_apiKey
}
};
}
});
// This logic (mostly) copied from appsync's apollo client creation
const link = ApolloLink.from([
apolloAuthLink,
onErrorLink,
ApolloLink.split(
operation => {
const { query } = operation;
const { kind, operation: graphqlOperation } = getMainDefinition(query);
const isSubscription =
kind === "OperationDefinition" && graphqlOperation === "subscription";
return isSubscription;
},
ApolloLink.from([
new NonTerminatingHttpLink(
"subsInfo",
{ uri: aws_config.aws_appsync_graphqlEndpoint },
true
),
new SubscriptionHandshakeLink("subsInfo")
]),
ApolloLink.from([
new HttpLink({ uri: aws_config.aws_appsync_graphqlEndpoint })
])
)
]);
return new ApolloClient({
connectToDevTools: process.browser,
ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
link,
cache: new InMemoryCache().restore(initialState)
});
};
export default createApolloClient;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment