Skip to content

Commit

Permalink
feat(@aws-amplify/api,graphql): DocumentNode support for GraphQL Clie…
Browse files Browse the repository at this point in the history
…nt (#2227)

* feat(@aws-amplify/api,graphql): DocumentNode support for GraphQL Client

Fixes #1237

* Update packages/api/src/API.ts

Co-Authored-By: manueliglesias <manuel.iglesias@gmail.com>
  • Loading branch information
manueliglesias authored Dec 3, 2018
1 parent fe8948d commit f31d649
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 10 deletions.
69 changes: 69 additions & 0 deletions packages/api/__tests__/API-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,75 @@ describe('API test', () => {
expect(spyon).toBeCalledWith(url, init);
});

test('happy-case-query-ast', 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
})
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
};

const body = {
query,
variables,
};

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

await api.graphql(graphqlOperation(doc, variables));

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

test('happy-case-query-oidc', async () => {
const spyonAuth = jest.spyOn(Credentials, 'get').mockImplementationOnce(() => {
return new Promise((res, rej) => {
Expand Down
15 changes: 6 additions & 9 deletions packages/api/src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,11 @@ export default class APIClass {
* @param {GraphQLOptions} GraphQL Options
* @returns {Promise<GraphQLResult> | Observable<object>}
*/
graphql({ query, variables = {} }: GraphQLOptions) {
graphql({ query: paramQuery, variables = {} }: GraphQLOptions) {

const doc = parse(query);
const query = typeof paramQuery === 'string' ? parse(paramQuery) : parse(print(paramQuery));

const [operationDef = {},] = doc.definitions.filter(def => def.kind === 'OperationDefinition');
const [operationDef = {},] = query.definitions.filter(def => def.kind === 'OperationDefinition');
const { operation: operationType } = operationDef as OperationDefinitionNode;

switch (operationType) {
Expand All @@ -343,7 +343,7 @@ export default class APIClass {
throw new Error(`invalid operation type: ${operationType}`);
}

private async _graphql({ query: queryStr, variables }: GraphQLOptions, additionalHeaders = {})
private async _graphql({ query, variables }: GraphQLOptions, additionalHeaders = {})
: Promise<GraphQLResult> {
if (!this._api) {
await this.createInstance();
Expand All @@ -357,20 +357,17 @@ export default class APIClass {
graphql_endpoint_iam_region: customEndpointRegion
} = this._options;

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

const headers = {
...(!customGraphqlEndpoint && await this._headerBasedAuth()),
...(customGraphqlEndpoint &&
(customEndpointRegion ? await this._headerBasedAuth('AWS_IAM') : { Authorization: null })
),
...additionalHeaders,
... await graphql_headers({ query: doc, variables }),
... await graphql_headers({ query, variables }),
};

const body = {
query,
query: print(query),
variables,
};

Expand Down
3 changes: 2 additions & 1 deletion packages/api/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
import { DocumentNode } from 'graphql/language/ast';

/**
* RestClient instance options
Expand Down Expand Up @@ -66,7 +67,7 @@ export interface apiOptions {
}

export interface GraphQLOptions {
query: string,
query: string | DocumentNode,
variables?: object,
}

Expand Down

0 comments on commit f31d649

Please sign in to comment.