AppSync to MongoDB

Connect directly to MongoDB Atlas cluster using AWS AppSync using HTTP resolvers.

AWS AppSyncMongoDB Atlas API
import * as cdk from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as path from 'path'
import * as appsync from 'aws-cdk-lib/aws-appsync'
import { PolicyStatement } from 'aws-cdk-lib/aws-iam'

interface AppsyncMongoStackProps extends cdk.StackProps {
	MONGO_SECRET_ARN: string
}

export class AppsyncMongoStack extends cdk.Stack {
	constructor(scope: Construct, id: string, props: AppsyncMongoStackProps) {
		super(scope, id, props)

		//create our API
		const api = new appsync.GraphqlApi(this, 'AppSyncToMongoAPI', {
			name: 'AppSyncToMongoAPI',
			schema: appsync.SchemaFile.fromAsset(
				path.join(__dirname, 'graphql/schema.graphql')
			),
			authorizationConfig: {
				defaultAuthorization: {
					authorizationType: appsync.AuthorizationType.API_KEY,
				},
			},
			logConfig: {
				fieldLogLevel: appsync.FieldLogLevel.ALL,
			},
			xrayEnabled: true,
		})

		// Create our 2 datasources

		// Secrets Manager
		const secretsManagerDS = api.addHttpDataSource(
			'secretsManager',
			`https://secretsmanager.${process.env.CDK_DEFAULT_REGION}.amazonaws.com`,
			{
				authorizationConfig: {
					signingRegion: `${process.env.CDK_DEFAULT_REGION}`,
					signingServiceName: 'secretsmanager',
				},
			}
		)

		// The MongoDB API
		const mongoDataAPIDS = api.addHttpDataSource(
			'mongoDBAtlasCluster',
			'https://data.mongodb-api.com'
		)

		// policy to permit an http datasource to get a secret in Secrets Manager
		secretsManagerDS.grantPrincipal.addToPrincipalPolicy(
			new PolicyStatement({
				resources: [props.MONGO_SECRET_ARN],
				actions: ['secretsmanager:GetSecretValue'],
			})
		)
		///////////////
		// Create a function that gets the secret
		const getMongoSecretFunc = new appsync.AppsyncFunction(
			this,
			'getMongoSecretFunc',
			{
				api,
				dataSource: secretsManagerDS,
				name: 'getMongoSecretFromSSM',
				code: appsync.Code.fromAsset(
					path.join(__dirname, '/graphql/mappings/getMongoSecret.js')
				),
				runtime: appsync.FunctionRuntime.JS_1_0_0,
			}
		)

		////////////////

		// Create a function that will list the Applicants from MongoDB
		const listApplicantsFunction = new appsync.AppsyncFunction(
			this,
			'listApplicantsFunction',
			{
				api,
				dataSource: mongoDataAPIDS,
				name: 'listApplicantsFunction',
				code: appsync.Code.fromAsset(
					path.join(__dirname, '/graphql/mappings/listApplicants.js')
				),
				runtime: appsync.FunctionRuntime.JS_1_0_0,
			}
		)

		////////////////////
		// Create a function that will add an Applicant to MongoDB
		const addApplicantFunction = new appsync.AppsyncFunction(
			this,
			'addApplicantFunction',
			{
				api,
				dataSource: mongoDataAPIDS,
				name: 'addApplicantFunction',
				code: appsync.Code.fromAsset(
					path.join(__dirname, '/graphql/mappings/addApplicant.js')
				),
				runtime: appsync.FunctionRuntime.JS_1_0_0,
			}
		)
		///////////////

		// Create a pipeline that has a "before" and "after" step + our fns
		const listApplicantsPipelineResolver = new appsync.Resolver(
			this,
			'listApplicantsPipelineResolver',
			{
				api,
				typeName: 'Query',
				fieldName: 'listApplicants',
				runtime: appsync.FunctionRuntime.JS_1_0_0,
				code: appsync.Code.fromAsset(
					path.join(__dirname, '/graphql/mappings/pipeline.js')
				),
				pipelineConfig: [getMongoSecretFunc, listApplicantsFunction],
			}
		)

		///////////////////

		// Create a pipeline that has a "before" and "after" step + our fns
		const addApplicantPipelineResolver = new appsync.Resolver(
			this,
			'addApplicantPipelineResolver',
			{
				api,
				typeName: 'Mutation',
				fieldName: 'addApplicant',
				runtime: appsync.FunctionRuntime.JS_1_0_0,
				code: appsync.Code.fromAsset(
					path.join(__dirname, '/graphql/mappings/pipeline.js')
				),
				pipelineConfig: [getMongoSecretFunc, addApplicantFunction],
			}
		)

		//////////////////////////
		new cdk.CfnOutput(this, 'appsync api key', {
			value: api.apiKey!,
		})

		new cdk.CfnOutput(this, 'appsync endpoint', {
			value: api.graphqlUrl,
		})

		new cdk.CfnOutput(this, 'appsync apiId', {
			value: api.apiId,
		})
	}
}

Download

git clone https://github.com/aws-samples/serverless-patterns
cd serverless-patterns/appsync-mongodb

Pattern repository

View on GitHub

Last updated on 26 Dec 2024

Edit this page