Last active
January 11, 2022 14:36
-
-
Save revmischa/740bac23c85023a0b31a0f4a8206f459 to your computer and use it in GitHub Desktop.
AWS AppSync Call From Lambda - using the AWS NodeJS SDK v3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
- Enable IAM authentication | |
- Grant IAM permission to lambda function | |
*/ | |
import { HttpRequest } from "@aws-sdk/protocol-http" | |
import { parseUrl } from "@aws-sdk/url-parser" | |
import { Response, got, RequestError } from "got" | |
import { GraphQLResponse } from "graphql-request/dist/types" | |
import { signHttpRequest } from "./signedAwsRequest" | |
export interface AppSyncHttpRequestArgs<T = Record<string, any>> { | |
query: string // graphql document | |
operationName: string // should match the name of the query document | |
variables?: T | |
} | |
export const appSyncHttpRequest = async <T>({ query, operationName, variables }: AppSyncHttpRequestArgs<T>) => { | |
// get appsync URL | |
const url = process.env.GRAPHQL_URL | |
// graphql query | |
const body = JSON.stringify({ | |
query, | |
operationName, | |
variables, | |
}) | |
// sign request | |
const parsedUrl = parseUrl(url) | |
const request = new HttpRequest({ | |
...parsedUrl, | |
method: "POST", | |
body, | |
headers: { | |
host: parsedUrl.hostname, | |
"content-type": "application/json", | |
}, | |
}) | |
const signedRequest = await signHttpRequest({ service: "appsync", request }) | |
// do AppSync HTTP request | |
let res: Response<string> | |
try { | |
// send graphql query to endpoint | |
res = await got({ | |
method: "POST", | |
url, | |
headers: signedRequest.headers, | |
body: signedRequest.body, | |
}) | |
} catch (ex: any) { | |
// HTTP error | |
console.error(`Failed request to ${url}`, (ex as RequestError).response?.body) | |
throw ex | |
} | |
// parse response | |
const jsonRes: GraphQLResponse<T> = JSON.parse(res.body) | |
if (jsonRes.errors?.length) { | |
// graphql error response | |
throw new Error(`GraphQL error response: ` + JSON.stringify(jsonRes.errors)) | |
} | |
return jsonRes.data | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { HttpRequest } from "@aws-sdk/protocol-http" | |
import { SignatureV4 } from "@aws-sdk/signature-v4" | |
import { defaultProvider } from "@aws-sdk/credential-provider-node" | |
import { Sha256 } from "@aws-crypto/sha256-js" | |
interface SignHttpRequestArgs { | |
request: HttpRequest | |
service: string // e.g. "appsync" | |
region?: string | |
} | |
export const signHttpRequest = async ({ request, service, region }: SignHttpRequestArgs) => { | |
region = region || process.env.AWS_DEFAULT_REGION | |
if (!region) throw new Error("Region required") | |
const signer = new SignatureV4({ | |
credentials: defaultProvider(), | |
region, | |
service, | |
sha256: Sha256, | |
}) | |
return signer.sign(request) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment