Skip to content

Commit

Permalink
feat(@aws-amplify/api): pass additionalHeaders to graphql function (#…
Browse files Browse the repository at this point in the history
…5001)

Additional headers are merged **after** merging in headers set at config time.
Additional headers will overwrite any existing values and merge the rest.
  • Loading branch information
jensbodal committed Mar 3, 2020
1 parent 8f6acca commit 44b4faf
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 3 deletions.
94 changes: 94 additions & 0 deletions packages/api/__tests__/API-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,100 @@ describe('API test', () => {

expect(spyon).toBeCalledWith(url, init);
});

test('happy case query with additionalHeaders', async () => {
const spyonAuth = jest
.spyOn(Credentials, 'get')
.mockImplementationOnce(() => {
return new Promise((res, rej) => {
res('cred');
});
});

const spyon = jest
.spyOn(RestClient.prototype, 'post')
.mockImplementationOnce((url, init) => {
return new Promise((res, rej) => {
res({});
});
});

const api = new API(config);
const url = 'https://appsync.amazonaws.com',
region = 'us-east-2',
apiKey = 'secret_api_key',
variables = { id: '809392da-ec91-4ef0-b219-5238a8f942b2' };
api.configure({
aws_appsync_graphqlEndpoint: url,
aws_appsync_region: region,
aws_appsync_authenticationType: 'API_KEY',
aws_appsync_apiKey: apiKey,
graphql_headers: async () =>
Promise.resolve({
someHeaderSetAtConfigThatWillBeOverridden: 'initialValue',
someOtherHeaderSetAtConfig: 'expectedValue',
}),
});
const GetEvent = `query GetEvent($id: ID! $nextToken: String) {
getEvent(id: $id) {
id
name
where
when
description
comments(nextToken: $nextToken) {
items {
commentId
content
createdAt
}
}
}
}`;

const doc = parse(GetEvent);
const query = print(doc);

const headers = {
Authorization: null,
'X-Api-Key': apiKey,
'x-amz-user-agent': Constants.userAgent,
};

const body = {
query,
variables,
};

const init = {
headers,
body,
signerServiceInfo: {
service: 'appsync',
region,
},
};

const additionalHeaders = {
someAddtionalHeader: 'foo',
someHeaderSetAtConfigThatWillBeOverridden: 'expectedValue',
};

await api.graphql(
graphqlOperation(GetEvent, variables),
additionalHeaders
);

expect(spyon).toBeCalledWith(url, {
...init,
headers: {
someAddtionalHeader: 'foo',
someHeaderSetAtConfigThatWillBeOverridden: 'expectedValue',
...init.headers,
someOtherHeaderSetAtConfig: 'expectedValue',
},
});
});
});

describe('configure test', () => {
Expand Down
10 changes: 7 additions & 3 deletions packages/api/src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,13 @@ export default class APIClass {
* Executes a GraphQL operation
*
* @param {GraphQLOptions} GraphQL Options
* @param {object} additionalHeaders headers to merge in after any `graphql_headers` set in the config
* @returns {Promise<GraphQLResult> | Observable<object>}
*/
graphql({ query: paramQuery, variables = {}, authMode }: GraphQLOptions) {
graphql(
{ query: paramQuery, variables = {}, authMode }: GraphQLOptions,
addtionalHeaders?: { [key: string]: string }
) {
const query =
typeof paramQuery === 'string'
? parse(paramQuery)
Expand All @@ -365,7 +369,7 @@ export default class APIClass {
switch (operationType) {
case 'query':
case 'mutation':
return this._graphql({ query, variables, authMode });
return this._graphql({ query, variables, authMode }, addtionalHeaders);
case 'subscription':
return this._graphqlSubscribe({
query,
Expand Down Expand Up @@ -399,8 +403,8 @@ export default class APIClass {
(customEndpointRegion
? await this._headerBasedAuth(authMode)
: { Authorization: null })),
...additionalHeaders,
...(await graphql_headers({ query, variables })),
...additionalHeaders,
...(!customGraphqlEndpoint && {
[USER_AGENT_HEADER]: Constants.userAgent,
}),
Expand Down

0 comments on commit 44b4faf

Please sign in to comment.