Created
January 29, 2023 15:49
-
-
Save leegilmorecode/78ef4441134e1b47f3269eec1ee1c083 to your computer and use it in GitHub Desktop.
Example of a AppSync Lambda function resolver using IAM and SigV4 to communicate with private API Gateways
This file contains 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 { AppSyncResolverEvent, AppSyncResolverHandler } from "aws-lambda"; | |
import { Customer } from "../../types"; | |
import { HttpRequest } from "@aws-sdk/protocol-http"; | |
import { URL } from "url"; | |
import fetch from "node-fetch"; | |
import { signRequest } from "../../helpers/request-signer"; | |
import { config } from "../../config"; | |
import { v4 as uuid } from "uuid"; | |
type CreateCustomerInput = { | |
input: { | |
firstName: string; | |
surname: string; | |
}; | |
}; | |
export const handler: AppSyncResolverHandler< | |
CreateCustomerInput, | |
Customer | |
> = async ( | |
event: AppSyncResolverEvent<CreateCustomerInput, Record<string, any> | null> | |
): Promise<Customer> => { | |
try { | |
const correlationId = uuid(); | |
const method = "create-customer.handler"; | |
const prefix = `${correlationId} - ${method}`; | |
// get the url for the customers domain | |
const customersDomainUrl = config.get("customersDomainUrl"); | |
console.log(`${prefix} - started`); | |
console.log(`${prefix} - customersDomainUrl: ${customersDomainUrl}`); | |
const { firstName, surname } = event.arguments.input; | |
const url = new URL(`${customersDomainUrl}/customers/`); | |
// very basic validation here for the demo | |
if (!firstName) throw new Error("firstName not supplied"); | |
if (!surname) throw new Error("surname not supplied"); | |
// create a new customer using the payload from appsync | |
const customer: Customer = { | |
firstName, | |
surname, | |
}; | |
// create the request which will be signed and sent to the private api via privatelink | |
const request = new HttpRequest({ | |
hostname: url.host, // https://12345.execute-api.eu-west-1.amazonaws.com/ | |
method: "POST", | |
body: JSON.stringify(customer), | |
headers: { | |
host: url.host, | |
"x-consumer-id": "experience-layer-bff", // pass through headers for logging of consumers | |
}, | |
path: url.pathname, // prod/customers/ | |
}); | |
console.log(`${prefix} - sending request: ${JSON.stringify(request)}`); | |
// sign our request with SigV4 and send | |
const signedRequest = await signRequest(request); | |
const response = await fetch(url.href, signedRequest); | |
const responseJson = (await response.json()) as Customer; | |
console.log( | |
`${prefix} - request response: ${JSON.stringify(responseJson)}` | |
); | |
// send the response back to appsync | |
return responseJson; | |
} catch (error) { | |
console.log(`Error: ${error}`); | |
throw error; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment