Flutter & GraphQL: Connecting a Flutter App to an AWS AppSync API Built with CDK

Mo Malaka
Flutter Community
Published in
5 min readDec 17, 2023
Photo by Artur Shamsutdinov on Unsplash

Introduction

In this post, I’ll walk through how to use the AWS Cloud Development Kit (AWS CDK) and the Amplify Data construct, recently launched by AWS Amplify, to define a GraphQL API backend using AWS AppSync. I’ll then demonstrate how to connect a Flutter application to that API using the Amplify Flutter library.

Developers can you the following options for deploying Amplify’s GraphQL API capabilities.

  • Amplify Command Line Interface (CLI) — Provides a streamlined toolchain that automates the creation and connection of AWS services like AppSync for frontend apps.
  • AWS CDK — Allows developers to programmatically define backend resources like GraphQL APIs, databases, authorization rules, and more using Infrastructure-as-Code.
  • Amplify (Gen 2) — On November 21, 2023, AWS Amplify announced a public preview of the next generation of full-stack app building in Amplify. With the code-first approach of Amplify (Gen 2), developers can define and provision cloud resources for use cases like authentication and data using CDK and TypeScript.

The choice depends on the app requirements and developer preferences. The Amplify CLI offers simplicity, while the CDK provides flexibility. Both tools integrate Amplify’s GraphQL capabilities, automating backend configuration. The Amplify team recommends for new GA apps using the AWS CDK construct when the primary use cases are configuring Auth or Data.

Clone the repo

For this post, I’ll be using this repository which contains the following projects:

  • cdk_backend: An AWS CDK project to create a GraphQL API backend using AWS AppSync.
  • flutter_todo_app: A Flutter web application that enables users to create and manage to-do items. This app will integrate with the GraphQL API deployed by the CDK backend.
  • graphql: Contains the GraphQL schema shared by both cdk_backend and flutter_todo_app .

Step 1: Clone the repo using the following command.


git clone https://github.com/offlineprogrammer/flutter_graphql.git

Step 2: Open the repo using Visual Studio Code.

VS Code window with the cloned repo open.

Set up the CDK stack

Step 1: Using VS Code terminal, navigate to the cdk_backend root folder, and install the AWS Amplify Data package by running the following command.

npm install @aws-amplify/data-construct

Step 2: In cdk_backend/lib/cdk-backend-stack.ts , I use the AmplifyData construct to create an AWS AppSync API. It is based on the schema in graphql/schema.graphql and uses API_KEY authorization.

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { AmplifyData, AmplifyDataDefinition } from '@aws-amplify/data-construct';


export class CdkBackendStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

new AmplifyData(this, 'AmplifyCdkData', {
definition: AmplifyDataDefinition.fromFiles('../graphql/schema.graphql'),
authorizationModes: {
defaultAuthorizationMode: 'API_KEY',
apiKeyConfig: {
expires: cdk.Duration.days(30)
}
}
});
}
}

Step 3: Deploy the CDK stacks by running the following command.

cdk deploy

Step 4: The CDK will prepare the resources for deployment and will display the following prompt. Enter Y and press Enter.

The CDK preparing for deployment.

The CDK will deploy the stacks and display the confirmation below. Note the details of the deployed API; we’re going to use them in the next section.

CDK deploys the stacks.

Connect Flutter app to GraphQL API

Step 1: Using the VS Code terminal, navigate to the flutter_todo_app root folder and install its dependencies by running the following command.

flutter pub get

Step 2: Install the @aws-amplify/cli packages by running the following command.

npm install @aws-amplify/cli

Step 3: Run the following command to generate the GraphQL client helper models inside the lib/models folder.

npx @aws-amplify/cli codegen models   --model-schema ../graphql   --target flutter   --output-dir ./lib/models
The ModelProvider.dart and Todo.dart files within the models folder.

In home_page.dart, I’m using a GraphQL query to retrieve the list of to-do items and display them in a ListView widget. The page will also allow the user to delete a to-do item by using a GraphQL mutation.

Future<void> _refreshTodoItems() async {
try {
final request = ModelQueries.list(Todo.classType);
final response = await Amplify.API.query(request: request).response;
final todos = response.data?.items;
if (response.hasErrors) {
safePrint('errors: ${response.errors}');
return;
}
setState(() {
_todoItems = todos!.whereType<Todo>().toList();
});
} on ApiException catch (e) {
safePrint('Query failed: $e');
}
}

Future<void> _deleteToDoItem(Todo todoItem) async {
final request = ModelMutations.delete<Todo>(todoItem);
final response = await Amplify.API.mutate(request: request).response;
safePrint('Delete response: $response');
await _refreshTodoItems();
}

I’m using a form in the todo_item_page.dart file that allows the user to create or update a to-do item. This form will execute a GraphQL mutation when submitted to add or modify the item in the database.

if (_isCreate) {
// Create a new to-do item
final newEntry = Todo(
name: name,
description: description.isNotEmpty ? description : null,
complete: complete,
);
final request = ModelMutations.create(newEntry);
final response = await Amplify.API.mutate(request: request).response;
safePrint('Create result: $response');
} else {
// Update todoItem instead
final updateToDoItem = _todoItem!.copyWith(
name: name,
description: description.isNotEmpty ? description : null,
complete: complete,
);
final request = ModelMutations.update(updateToDoItem);
final response = await Amplify.API.mutate(request: request).response;
safePrint('Update result: $response');
}

Step 4: Update main.dart to configure Amplify using the details of the GraphQL API you created in the previous section using the Amplify GraphQL API CDK construct.

await Amplify.addPlugins([api]);
// TODO: Add the API details below
const amplifyconfig = '''{
"api": {
"plugins": {
"awsAPIPlugin": {
"flutter_todo_app": {
"endpointType": "GraphQL",
"endpoint": "<The-GrpahQL-Endpoint>",
"region": "<The-Region>",
"authorizationType": "API_KEY",
"apiKey": "<The-API-KEY-Value>"
}
}
}
}
}''';

Step 5: Run the app in the Chrome browser using the following command.

flutter run -d chrome

Clean up resources

Now that you’ve finished this walkthrough, make sure to delete the AWS resources to avoid incurring unexpected costs. You can do that using the VS Code terminal by navigating to the cdk_backend root folder and running the following command.

cdk destroy

Conclusion

Congratulations! You used the recently released AWS Amplify Data CDK construct to create a GraphQL API backend using AWS AppSync. Then you connected a Flutter application to that API using the Amplify Flutter library. If you have any feedback, leave a GitHub issue or join our Discord Community!

--

--

Mo Malaka
Flutter Community

Solutions Architect @aws-amplify | Lifelong Learner | Opinions are my own