Hi,
I am looking for the way to add a custom header in all the request sent to AppSync. I was able to do it with the Amplify library but since I need some the advanced functionnalities from aws-appsync-sdk, I am trying to do it with the appsync-sdk as well.
I didn't find any documentation on this topic. Is there a way to do it?
For example, I tried to add request option when creating the AWSAppSyncClient without any success:
const appSyncClient = new AWSAppSyncClient({
url: config.amplify_config.aws_appsync_graphqlEndpoint,
request: async (operation) => {
const user = await Auth.currentUserInfo();
logger.debug("AWSAppSyncClient request:", user);
operation.setContext({
headers: {
'amt-custom-username': user.username
}
});
},
region: config.amplify_config.aws_appsync_region,
auth: {
type: AUTH_TYPE.AWS_IAM,
credentials: () => Auth.currentCredentials(),
},
});
Hi @OlivierPT
Try this sample code here
In order to read the custom header on your request mapping template use this $context.request.headers.your_header_name
I used this on the previous sample
{
"version": "2017-02-28",
"payload": {
"id": "${context.arguments.id}",
"title": "$context.request.headers.hi"
}
}
Let me know how it goes
Hi @elorzafe ,
Thanks, it works! :)
Is this method not working after access-control-expose-headers was there (set to x-amzn-RequestId,x-amzn-ErrorType,x-amz-user-agent,x-amzn-ErrorMessage,Date,x-amz-schema-version)? I cannot seem to set the custom http headers now. Below are code in angular.
EDIT: Looks like I mistyped headers as header.
import { ApolloModule, APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { NgModule } from '@angular/core';
import { createAppSyncLink, AUTH_TYPE } from 'aws-appsync';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { HelloService } from './hello.service';
export function createApollo(httpLink: HttpLink, hello: HelloService) {
const url = 'https://xxxxxxxxxxxxxxxxxxxxxxxxxx.appsync-api.us-east-1.amazonaws.com/graphql';
const link = createAppSyncLink({
url,
region: 'us-east-1',
auth: {
type: AUTH_TYPE.API_KEY,
apiKey: 'da2-xxxxxxxxxxxxxxxxxxxxxxxxxx'
},
complexObjectsCredentials: null,
resultsFetcherLink: ApolloLink.from([
setContext(async (request, previousContext) => {
const context = {
header: {
...previousContext.headers,
ticket: await hello.say('world').toPromise()
}
};
console.log(context);
return context;
}),
createHttpLink({ uri: url })
]),
});
return { cache: new InMemoryCache(), link };
}
@NgModule({
exports: [ApolloModule, HttpLinkModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink, HelloService],
},
],
})
export class GraphQLModule { }
@elorzafe you are an absolute legend. Copied your sample into my project and used $context.request.headers.your_header_name in my request mapping to get my custom header. Worked first time!
In my case I am accessing a graphql api through a lambda and using IAM credentials. Here is my code to setup the AWSAppSyncClient if anyone is interested.
const AWS = require('aws-sdk');
const AWSAppSyncClient = require('aws-appsync').default;
const { createAppSyncLink } = require('aws-appsync');
require('es6-promise').polyfill();
require('isomorphic-fetch');
const { ApolloLink } = require('apollo-link');
const { createHttpLink } = require('apollo-link-http');
const { setContext } = require('apollo-link-context');
const buildApiClient = (connection, customHeaders) => {
const { URL, REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN } = connection;
AWS.config.update({
region: REGION,
credentials: new AWS.Credentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN),
});
const { credentials } = AWS.config;
const AppSyncConfig = {
url: URL,
region: REGION,
auth: {
type: 'AWS_IAM',
credentials,
},
disableOffline: true,
};
const appsyncClient = new AWSAppSyncClient(AppSyncConfig, {
defaultOptions: {
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
},
},
link: createAppSyncLink({
...AppSyncConfig,
resultsFetcherLink: ApolloLink.from([
setContext((request, previousContext) => ({
headers: {
...previousContext.headers,
...customHeaders,
},
})),
createHttpLink({
uri: AppSyncConfig.url,
}),
]),
}),
});
return appsyncClient;
};
module.exports = buildApiClient;
What about response headers?
I have resolver as HTTP URL which returns some headers as well. But those response headers are not coming in-appsync response? While I can access the response headers using $context.result.headers and it's working but how can i pass these as headers in appsync response.
I solved my problem with this
import React from 'react'
import AWSAppSyncClient, { createAppSyncLink } from 'aws-appsync'
import { ApolloProvider } from '@apollo/react-hooks'
import { ApolloLink, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
import AppSyncConfig from '@components/aws-config'
import { get } from '@common/Lodash'
const apolloClient = props => {
const token = sessionStorage.getItem('token')
const AppSyncProps = {
url: AppSyncConfig.graphqlEndpoint,
region: AppSyncConfig.region,
auth: {
type: AppSyncConfig.authenticationType,
apiKey: AppSyncConfig.apiKey,
},
disableOffline: true,
}
const apolloPartialProps = {
link: createAppSyncLink({
...AppSyncProps,
resultsFetcherLink: ApolloLink.from([
setContext((request, previousContext) => ({
headers: {
...previousContext.headers,
'x-api-key': token,
},
})),
createHttpLink({
uri: AppSyncProps.url,
}),
]),
}),
}
return new AWSAppSyncClient(AppSyncProps, apolloPartialProps)
}
export const client = apolloClient()
export const GraphqlProvider = ({ children }) => (
<ApolloProvider client={client}>{children}</ApolloProvider>
)
export default GraphqlProvider
Note @apollo/client and @apollo/react-hooks
Most helpful comment
Hi @OlivierPT
Try this sample code here
In order to read the custom header on your request mapping template use this $context.request.headers.your_header_name
I used this on the previous sample
Let me know how it goes