Page updated Mar 1, 2024

Connect to existing AWS resources built with the CDK

This guide shows you how to connect a new app to AWS resources you've already created using the AWS Cloud Development Kit (AWS CDK). The AWS CDK is an open-source software development framework for defining cloud infrastructure as code with modern programming languages. This infrastructure is then deployed through AWS CloudFormation.

In this guide, you will use the Amplify Data CDK to create a GraphQL API backend with AWS AppSync. This creates the core backend. You will then create and connect a React web app to the GraphQL API.

Before you begin, you will need:

  • An AWS account: If you don't already have an account, follow the Setting Up Your AWS Environment tutorial for a quick overview.
  • The Amplify CLI installed and configured.
  • A text editor. For this guide, we will use VS Code, but you can use your preferred IDE.

Build a GraphQL API using the Amplify Data CDK construct

The CDK provides a simple way to define cloud infrastructure in code. In this section, we will use the CDK to build out the backend resources for our application.

Step 1: Create a folder for the CDK app by running the following command in your terminal.

Terminal
mkdir cdk-backend

Step 2: Navigate to the cdk-backend folder and create a new CDK project by running the cdk init command and specifying your preferred language.

Terminal
1cd cdk-backend
2cdk init --language typescript

Step 3: Open the newly created CDK project using VS Code, or your preferred IDE.

Step 4: In your terminal, navigate to the cdk_backend root folder, and install the AWS Amplify Data package by running the following command.

Terminal
npm install @aws-amplify/data-construct

Step 5: Update the cdk_backend/lib/cdk-backend-stack.ts file as shown in the following code to use the AmplifyData construct to create an AWS AppSync API.

lib/cdk-backend-stack.ts
1import * as cdk from 'aws-cdk-lib';
2import { Construct } from 'constructs';
3import {
4 AmplifyData,
5 AmplifyDataDefinition
6} from '@aws-amplify/data-construct';
7
8export class CdkBackendStack extends cdk.Stack {
9 constructor(scope: Construct, id: string, props?: cdk.StackProps) {
10 super(scope, id, props);
11
12 new AmplifyData(this, 'AmplifyCdkData', {
13 definition: AmplifyDataDefinition.fromString(/* GraphQL */ `
14 type Todo @model @auth(rules: [{ allow: public }]) {
15 id: ID!
16 name: String!
17 description: String
18 complete: Boolean
19 }
20 `),
21 authorizationModes: {
22 defaultAuthorizationMode: 'API_KEY',
23 apiKeyConfig: {
24 expires: cdk.Duration.days(30)
25 }
26 }
27 });
28 }
29}

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

cdk deploy

Step 7: 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 following confirmation. Note the details of the deployed API; we’re going to use them in the next section.

CDK deploying the stacks.

Now that you have built the backend API with the CDK, you can connect a frontend.

Build a React app and connect to the GraphQL API

In this section, we will connect a React web app to our existing GraphQL API. First, we will create a new React project and install the necessary Amplify packages. Next, we will use the Amplify CLI to generate GraphQL code matching our API structure. Then, we will add React components to perform queries and mutations to manage to-do items in our API. After that, we will configure the Amplify library with details of our backend API. Finally, we will run the application to demonstrate full CRUD functionality with our existing API.

Step 1: Create a React app by running the following command in your terminal.

Terminal
npx create-react-app react-amplify-connect

Step 2: Open the newly created React app using VS Code, or your preferred IDE.

Step 3: Install the aws-amplify, @aws-amplify/ui-react, and @aws-amplify/cli packages by running the following commands.

Terminal
npm install aws-amplify @aws-amplify/ui-react @aws-amplify/cli

Step 4: Use the awsAppsyncApiId and awsAppsyncRegion values of the CDK stack you created previously to generate the GraphQL client helper code by running the following command.

awsAppsyncApiId and awsAppsyncRegion values highlighted within the outputs of the CDK stack.
npx @aws-amplify/cli codegen add --apiId <aws-appsync-api-id> --region <aws-appsync-region>

Step 5: Accept the default values for the prompts.

Terminal
? Choose the type of app that you're building javascript
? What javascript framework are you using react
✔ Getting API details
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
✔ Downloaded the schema
✔ Generated GraphQL operations successfully and saved at src/graphql

The Amplify CLI will create the GraphQL client helper code inside the src/graphql folder.

mutations.js, queries.js, and subscriptions.js within the graphql folder.

Step 6: Update the App.js file with the following code to create a form with a button to create to-dos, as well as a way to fetch and render the to-do list.

src/App.js
1import { Amplify} from 'aws-amplify'
2import '@aws-amplify/ui-react/styles.css';
3import { useEffect, useState } from 'react';
4import { generateClient } from 'aws-amplify/api';
5import { createTodo } from './graphql/mutations';
6import { listTodos } from './graphql/queries';
7
8Amplify.configure({
9 API: {
10 GraphQL: {
11 endpoint: '<your-graphql-endpoint>',
12 region: '<your-aws-region>',
13 defaultAuthMode: 'apiKey',
14 apiKey: '<your-api-key>'
15 }
16 }
17});
18
19const initialState = { name: '', description: '' };
20const client = generateClient();
21
22const App = () => {
23 const [formState, setFormState] = useState(initialState);
24 const [todos, setTodos] = useState([]);
25
26 useEffect(() => {
27 fetchTodos();
28 }, []);
29
30 function setInput(key, value) {
31 setFormState({ ...formState, [key]: value });
32 }
33
34 async function fetchTodos() {
35 try {
36 const todoData = await client.graphql({
37 query: listTodos
38 });
39 const todos = todoData.data.listTodos.items;
40 setTodos(todos);
41 } catch (err) {
42 console.log('error fetching todos');
43 }
44 }
45
46 async function addTodo() {
47 try {
48 if (!formState.name || !formState.description) return;
49 const todo = { ...formState };
50 setTodos([...todos, todo]);
51 setFormState(initialState);
52 await client.graphql({
53 query: createTodo,
54 variables: {
55 input: todo
56 }
57 });
58 } catch (err) {
59 console.log('error creating todo:', err);
60 }
61 }
62
63 return (
64 <div style={styles.container}>
65 <h2>Amplify Todos</h2>
66 <input
67 onChange={(event) => setInput('name', event.target.value)}
68 style={styles.input}
69 value={formState.name}
70 placeholder="Name"
71 />
72 <input
73 onChange={(event) => setInput('description', event.target.value)}
74 style={styles.input}
75 value={formState.description}
76 placeholder="Description"
77 />
78 <button style={styles.button} onClick={addTodo}>
79 Create Todo
80 </button>
81 {todos.map((todo, index) => (
82 <div key={todo.id ? todo.id : index} style={styles.todo}>
83 <p style={styles.todoName}>{todo.name}</p>
84 <p style={styles.todoDescription}>{todo.description}</p>
85 </div>
86 ))}
87 </div>
88 );
89};
90
91const styles = {
92 container: {
93 width: 400,
94 margin: '0 auto',
95 display: 'flex',
96 flexDirection: 'column',
97 justifyContent: 'center',
98 padding: 20
99 },
100 todo: { marginBottom: 15 },
101 input: {
102 border: 'none',
103 backgroundColor: '#ddd',
104 marginBottom: 10,
105 padding: 8,
106 fontSize: 18
107 },
108 todoName: { fontSize: 20, fontWeight: 'bold' },
109 todoDescription: { marginBottom: 0 },
110 button: {
111 backgroundColor: 'black',
112 color: 'white',
113 outline: 'none',
114 fontSize: 18,
115 padding: '12px 0px'
116 }
117};
118
119export default App;

Step 7: Run the app using the following command.

Terminal
npm start

Step 8: Use the form to create a few to-do items.

In this section, we generated GraphQL code, created React components, configured Amplify, and connected the app to the API. This enabled full CRUD functionality with our backend through queries and mutations.

Conclusion

Congratulations! You used the AWS Amplify Data CDK construct to create a GraphQL API backend using AWS AppSync. You then connected your app to that API using the Amplify libraries. If you have any feedback, leave a GitHub issue or join our Discord Community!

Clean up resources

Once you're finished experimenting with this demo app, we recommend deleting the backend resources to avoid incurring unexpected costs. You can do this by running the following command in the root folder of the CDK app created above.

Terminal
cdk destroy