AWS AppSync is a serverless GraphQL and Pub/Sub API service that many builders love. Turing the advanced job of making and managing a GraphQL API with real-time capabilities into a number of strains of IaC (or clicks within the console) is a good win for AWS serverless builders.
The AWS AppSync lets you combine with different AWS companies by way of AWS Lambda capabilities or VTL mapping templates. Traditionally it was fairly laborious to check the logic written within the VTL templates. Because the service matured, AWS added an increasing number of methods to take action, enabling us, builders, to make sure the service we’re growing is working accurately.
On this weblog put up, I’ll showcase all of the methods for testing AWS AppSync VTL templates I’ve seen within the wild. This, under no circumstances, is a complete listing – these are the methods I am accustomed to. If a distinct method, please be happy to achieve out!
You will discover the code for all of the methods listed within the article in this GitHub repository.
Testing VTL templates utilizing the AWS SDK
It is a method I’ve found just lately, and it rapidly grew to become my favourite. The AppSync SDK exposes the evaluate-mapping-template
CLI name for parsing AppSync VTL templates utilizing the AppSync SDK.
Once I examine this on this AWS weblog put up I used to be thrilled as I used to be not very happy with how I have been testing the templates up to now (one other technique that I’ll contact on on this article).
The take a look at boils all the way down to evaluating the VTL template by way of the AWS SDK, then asserting on the outcome. You’ve just one dependency to take care of – the AWS SDK for AppSync, which is a large win. The next is a snippet that evaluates a VTL template by way of the AppSync SDK answerable for fetching a consumer from AWS DynamoDB.
You will discover the complete supply code for this testing technique right here.
import {
AppSyncClient,
EvaluateMappingTemplateCommand
} from "@aws-sdk/client-appsync";
const shopper = new AppSyncClient({});
take a look at("template take a look at", async () => {
const template = `{
"model": "2018-05-29",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($context.arguments.id),
}
}`;
const context = JSON.stringify({ arguments: { id: "USER_ID" } });
const templateEvaluationResult = await shopper.ship(
new EvaluateMappingTemplateCommand({
template,
context
})
);
count on(templateEvaluationResult.evaluationResult).toMatchInlineSnapshot(`
"{
"model": "2018-05-29",
"operation": "GetItem",
"key": {
"id": {"S":"USER_ID"},
}
}"
`);
});
Since we’re utilizing the official AWS SDK, we will be fairly assured that if we have been to deploy an API and use this template, that is how the AWS AppSync service would render it internally.
One downside of this fashion of testing VTL templates is that the atmosphere wherein the take a look at is operating has to have entry to AWS credentials. That by no means was an issue for me, nevertheless it all is dependent upon your scenario, so be conscious of that.
Testing VTL templates utilizing VTL parsers
That is the method I’ve used earlier than I realized in regards to the AppSync SDK’s skill to render templates. As a substitute of counting on the SDK, we use libraries the AWS Amplify makes use of internally to render the template.
The take a look at setup is a little more concerned, however the result’s just about the identical as within the earlier instance. The next is the snippet rendering the VTL template utilizing Amplify VTL parsers.
You will discover the complete supply code for this testing technique right here.
import velocityUtil from "amplify-appsync-simulator/lib/velocity/util";
import velocityTemplate from "amplify-velocity-template";
import velocityMapper from "amplify-appsync-simulator/lib/velocity/value-mapper/mapper";
take a look at("template take a look at", async () => {
const template = `{
"model": "2018-05-29",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($context.arguments.id),
}
}`;
const errors: any[] = [];
const now = new Date();
const graphQLResolveInfo = {} as any;
const appSyncGraphQLExecutionContext = {} as any;
const vtlUtil = velocityUtil.create(
errors,
now,
graphQLResolveInfo,
appSyncGraphQLExecutionContext
);
const vtlAST = velocityTemplate.parse(template);
const vtlCompiler = new velocityTemplate.Compile(vtlAST, {
valueMapper: velocityMapper.map,
escape: false
});
const context = {
arguments: { id: "USER_ID" },
args: { id: "USER_ID" }
};
const renderedTemplate = vtlCompiler.render({
util: vtlUtil,
utils: vtlUtil,
ctx: context,
context
});
count on(renderedTemplate).toMatchInlineSnapshot(`
"{
"model": "2018-05-29",
"operation": "GetItem",
"key": {
"id": {"S":"USER_ID"},
}
}"
`);
});
As I discussed earlier, I am not a large fan of this method. My predominant gripe is that I’ve to tug further dependencies, which I’ve no confidence are nicely maintained, to my venture.
One other problem I’ve is that the dependencies may be outdated and yield a template that may be completely different than the one produced internally contained in the AWS AppSync service.
As for positives – since we do not make any calls to AWS, this method doesn’t require you to have AWS credentials in place. It may be an enormous plus for some, however not a lot for others.
Testing VTL templates utilizing AWS AppSync simulator
Subsequent up, going up within the complexity spectrum, this method sits in a bizarre spot between native emulation and exercising deployed AWS infrastructure.
As a substitute of rendering the template and asserting its form, we make use of the amplify-appsync-simulator
bundle to course of the template and make the request to an precise (or native occasion of) AWS service. This technique stands on the shoulders of the AWS Amplify mocking and testing capabilities.
You will discover the complete supply code for this testing technique right here.
import { AppSyncUnitResolver } from "amplify-appsync-simulator/lib/resolvers";
import {
AmplifyAppSyncSimulator,
AmplifyAppSyncSimulatorAuthenticationType,
RESOLVER_KIND
} from "amplify-appsync-simulator";
take a look at("template take a look at", async () => {
const simulator = new AmplifyAppSyncSimulator();
simulator.init({
dataSources: [
{
type: "AMAZON_DYNAMODB",
name: "dynamodb",
config: { tableName, endpoint: tableEndpoint }
}
],
appSync: {
title: "testAppSyncAPI",
additionalAuthenticationProviders: [],
defaultAuthenticationType: {
authenticationType: AmplifyAppSyncSimulatorAuthenticationType.API_KEY
}
},
schema: {
content material: `
schema {
question: Question
}
kind Question {
getUser(id: ID!): Person!
}
kind Person {
id: ID!
title: String!
}
`
}
});
const requestTemplate = `{
"model": "2018-05-29",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($context.arguments.id)
}
}`;
const responseTemplate = `$util.toJson($context.outcome)`;
const resolver = new AppSyncUnitResolver(
{
requestMappingTemplate: requestTemplate,
responseMappingTemplate: responseTemplate,
sort: RESOLVER_KIND.UNIT,
fieldName: "mockFieldName",
typeName: "mockTypeName",
dataSourceName: "dynamodb"
},
simulator
);
const outcome = await resolver.resolve(
"SOURCE",
{ id: "USER_ID" },
{
appsyncErrors: []
},
{
fieldNodes: []
}
);
count on(outcome).toMatchInlineSnapshot(`
{
"id": "USER_ID",
"title": "CREATED_AT_INFRASTRUCTURE_DEPLOY_TIME",
}
`);
});
To be completely sincere, I am not a large fan of this testing method. My greatest downside is the quantity of effort required to make the take a look at work. Along with pulling further dependencies into my venture, I’ve to both arrange an area mock of a given AWS service or deploy a given service earlier than the take a look at run.
Testing VTL templates by making GraphQL requests
And the final testing technique I’ve used are the end-to-end assessments. As a substitute of rendering the VTL template or utilizing simulation, one may hearth a GraphQL request to the API endpoint and assert the outcome. These assessments often run for for much longer than those I’ve beforehand talked about however the boldness you achieve that your system is working by using end-to-end assessments is very large.
The take a look at physique is tiny. We shift the complexity away from the take a look at setup to the infrastructure configuration. To make use of this testing method successfully, you will need to have already got all of the cloud assets associated to the AWS AppSync deployed.
You will discover the complete supply code for this testing technique right here.
import { gql, request } from "graphql-request";
take a look at("template take a look at", async () => {
const question = gql`
question {
getUser(id: "USER_ID") {
id
title
}
}
`;
const response = await request(
endpointUrl,
question,
{},
{
"x-api-key": endpointAPIkey
}
);
count on(response).toMatchInlineSnapshot(`
{
"getUser": {
"id": "USER_ID",
"title": "CREATED_AT_INFRASTRUCTURE_DEPLOY_TIME",
},
}
`);
});
This testing technique is my go-to once I wish to train the entire system I am engaged on.
Closing phrases
I’ve used these 4 AWS AppSync VTL testing methods with various levels of success. Hopefully, after studying this text, you discovered a method that matches your wants.
I am at all times open to suggestions and studying new issues. In case you are conscious of a distinct method of, immediately or not directly, testing VTL templates – please let me know!
Contemplate following me on Twitter – @wm.matuszewski in case you want to see extra serverless content material in your timeline.
Thanks in your treasured time.