<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dave Hudson</title>
    <description>The latest articles on DEV Community by Dave Hudson (@applification).</description>
    <link>https://dev.to/applification</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F198678%2F297d2080-4935-41aa-9ad9-a4ac14ad6ac1.jpg</url>
      <title>DEV Community: Dave Hudson</title>
      <link>https://dev.to/applification</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/applification"/>
    <language>en</language>
    <item>
      <title>How to use Amplify AppSync GraphQL types in a React TypeScript App</title>
      <dc:creator>Dave Hudson</dc:creator>
      <pubDate>Tue, 01 Dec 2020 10:41:13 +0000</pubDate>
      <link>https://dev.to/applification/how-to-use-amplify-appsync-graphql-types-in-a-react-typescript-app-of</link>
      <guid>https://dev.to/applification/how-to-use-amplify-appsync-graphql-types-in-a-react-typescript-app-of</guid>
      <description>&lt;p&gt;I recently had the task of performing a code review on a TypeScript project utilising NextJS and Amplify AppSync. The developer had opted for TypeScript because it would "prevent runtime errors for both backend and frontend". This is solid reasoning which I fully support, problem was this wasn't quite what was happening in reality.&lt;/p&gt;

&lt;p&gt;The AppSync GraphQL was strongly typed through the &lt;code&gt;schema.graphql&lt;/code&gt; file but the TypeScript frontend wasn't linked to those types in any way. The React code simply used the TypeScript &lt;code&gt;:any&lt;/code&gt; type meaning the code was effectively opting out of type checking. So how do you use the TypeScript types of an AppSync GraphQL API on the frontend of a React app?&lt;/p&gt;

&lt;p&gt;The Amplify CLI is pretty helpful and gets you most of the way there as it generates a types file when &lt;a href="https://docs.amplify.aws/cli/graphql-transformer/codegen#amplify-add-codegen"&gt;codegen&lt;/a&gt; is run. However, it turns out the generated types need some further manipulation as they contain &lt;code&gt;null&lt;/code&gt; values and &lt;code&gt;__typename&lt;/code&gt; properties. Additionally when actually making a GraphQL API call we get back a JSON response wrapped in a &lt;code&gt;data:&lt;/code&gt; object which our type doesn't expect.&lt;/p&gt;

&lt;p&gt;What follows is a detailed walkthrough of the steps I took to achieve a typed frontend, taking the generated types from Amplify and manipulating them into a format that can be used effectively on the frontend. &lt;/p&gt;

&lt;p&gt;If you want to bypass the walkthrough and jump straight to the code it's on &lt;a href="https://github.com/DaveHudson/next-typescript-appsync"&gt;Github&lt;/a&gt;. &lt;/p&gt;




&lt;h2&gt;
  
  
  Init NextJS TypeScript App
&lt;/h2&gt;

&lt;p&gt;First off I started out with a fresh NextJS project, nothing special, just an out of the box app configured with TypeScript following the NextJS docs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/getting-started#setup"&gt;https://nextjs.org/docs/getting-started#setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nextjs.org/docs/basic-features/typescript"&gt;https://nextjs.org/docs/basic-features/typescript&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app
&lt;span class="nb"&gt;touch &lt;/span&gt;tsconfig.json
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; typescript @types/react @types/node
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short we now have a NextJS app in TypeScript, we just need to start renaming &lt;code&gt;.js&lt;/code&gt; files to &lt;code&gt;.tsx&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Init Amplify
&lt;/h2&gt;

&lt;p&gt;If you haven't used Amplify before there are some prerequisites you may need to install and configure. See &lt;a href="https://docs.amplify.aws/start/getting-started/installation/q/integration/react"&gt;https://docs.amplify.aws/start/getting-started/installation/q/integration/react&lt;/a&gt;. These instructions follow on assuming you have already done these steps.&lt;/p&gt;

&lt;p&gt;Initialise a new Amplify backend with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;amplify init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I changed a few options specifically for NextJS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;? Enter a name &lt;span class="k"&gt;for &lt;/span&gt;the project nexttsappsync
? Enter a name &lt;span class="k"&gt;for &lt;/span&gt;the environment dev
? Choose your default editor: Visual Studio Code
? Choose the &lt;span class="nb"&gt;type &lt;/span&gt;of app that you are building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  ./
? Distribution Directory Path: out
? Build Command:  npm run-script build
? Start Command: npm run-script start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GraphQL Folder
&lt;/h2&gt;

&lt;p&gt;Next add an API to Amplify:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;amplify add api&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Choose &lt;code&gt;GraphQL&lt;/code&gt; as it's strongly typed which is ideal for our TypeScript frontend. Use the Todo generated single object with fields schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;? Please &lt;span class="k"&gt;select &lt;/span&gt;from one of the below mentioned services: GraphQL
? Provide API name: todoapi
? Choose the default authorization &lt;span class="nb"&gt;type &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;the API API key
? Enter a description &lt;span class="k"&gt;for &lt;/span&gt;the API key: todoAPIKey
? After how many days from now the API key should expire &lt;span class="o"&gt;(&lt;/span&gt;1-365&lt;span class="o"&gt;)&lt;/span&gt;: 365
? Do you want to configure advanced settings &lt;span class="k"&gt;for &lt;/span&gt;the GraphQL API No, I am &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
? Do you have an annotated GraphQL schema? No
? Choose a schema template: Single object with fields &lt;span class="o"&gt;(&lt;/span&gt;e.g., “Todo” with ID, name, description&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated &lt;code&gt;schema.graphql&lt;/code&gt; has a Todo model as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next configure amplify codegen and generate the TypeScript types based off our GraphQL Schema.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;amplify configure codegen&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the generation target language ensure you choose &lt;code&gt;typescript&lt;/code&gt;. For the filepath I set &lt;code&gt;graphql/**/*.ts&lt;/code&gt; because NextJS doesn't use a &lt;code&gt;src&lt;/code&gt; folder and I wanted everything generated inside a &lt;code&gt;graphql&lt;/code&gt; folder but you can generate to whatever filepath you like.&lt;/p&gt;

&lt;p&gt;Enter the file name and path for the generated code I used &lt;code&gt;graphql/API.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;? Enter a file name pattern of graphql queries, mutations and subscriptions graphql/&lt;span class="k"&gt;**&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.ts
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth &lt;span class="o"&gt;[&lt;/span&gt;increase from default &lt;span class="k"&gt;if &lt;/span&gt;your schema is deeply nested] 2
? Enter the file name &lt;span class="k"&gt;for &lt;/span&gt;the generated code graphql/API.ts
? Do you want to generate code &lt;span class="k"&gt;for &lt;/span&gt;your newly created GraphQL API Yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GraphiQL
&lt;/h2&gt;

&lt;p&gt;We now have a GraphQL API, create some Todo items for the frontend to play with by running &lt;code&gt;amplify mock&lt;/code&gt;. Mocking will create the underlying DynamoDB tables and spin up GraphiQL on a local url. You should see something like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AppSync Mock endpoint is running at http://192.168.86.161:20002&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open that link and you'll see GraphiQL. Create some data using a mutation as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt; &lt;span class="nx"&gt;MyMutation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;createTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Put out the bins&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You know what to do again&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a few more with your own todo name and description then use the following query to see your data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;MyQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;listTodos&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;id&lt;/span&gt;
      &lt;span class="nx"&gt;description&lt;/span&gt;
      &lt;span class="nx"&gt;createdAt&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;
      &lt;span class="nx"&gt;updatedAt&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case that yields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"listTodos"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"39e9cb83-d936-4b05-999d-61f412d57ecb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You know what to do again"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-11-25T10:21:39.407Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Put out the bins"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"updatedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-11-25T10:21:39.407Z"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dd2d975b-be52-4a23-8dfd-03e6a4a256ae"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The best chore!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-11-25T10:22:20.674Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hoover up lounge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"updatedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-11-25T10:22:20.674Z"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8bce419d-39d5-425b-ab45-00f731e0454e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You know what to do"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-11-25T10:21:31.577Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Put out the recycling"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"updatedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2020-11-25T10:21:31.577Z"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the structure of the returned JSON. There is a data object, which has a &lt;code&gt;listTodos&lt;/code&gt; object, which contains an &lt;code&gt;items&lt;/code&gt; array. Each array item has properties that are defined by our strongly typed &lt;code&gt;schema.graphql&lt;/code&gt; file. You'll also notice some utility properties have been added automatically by Amplify, specifically &lt;code&gt;createdAt&lt;/code&gt; and &lt;code&gt;updatedAt&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  React
&lt;/h2&gt;

&lt;p&gt;Moving to the frontend lets get Amplify set up with our React App. First we need to install Amplify and the Amplify GraphQL library.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i aws-amplify @aws-amplify/api-graphql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Rename &lt;code&gt;pages/index.js&lt;/code&gt; to &lt;code&gt;pages/index.tsx&lt;/code&gt; then add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Amplify&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-amplify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;awsExports&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../aws-exports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;Amplify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;awsExports&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;npm run dev&lt;/code&gt; and it should show the out of the box NextJS app running on &lt;code&gt;http://localhost:3000&lt;/code&gt;. The only difference being we've connected Amplify to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL Integration
&lt;/h2&gt;

&lt;p&gt;Take a look in the &lt;code&gt;graphql&lt;/code&gt; folder, note the &lt;code&gt;queries.ts&lt;/code&gt;, &lt;code&gt;mutations.ts&lt;/code&gt;, &lt;code&gt;subscriptions.ts&lt;/code&gt; files and the &lt;code&gt;API.ts&lt;/code&gt; file from the codegen command. Lets make our imports easier by creating the file &lt;code&gt;/graphql/index.tsx&lt;/code&gt; and adding the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./API&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./mutations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./queries&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./subscriptions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now import our types and queries from the same place. Back in the &lt;code&gt;pages/index.tsx&lt;/code&gt; file import the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GraphQLAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GRAPHQL_AUTH_MODE&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-amplify/api-graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;listTodos&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add some code to fetch our todos using the generated &lt;code&gt;listTodos&lt;/code&gt; query and specifying the API_KEY as the authorization mode for our GraphQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;GraphQLAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;authMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GRAPHQL_AUTH_MODE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;fetchTodos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all went well you should see the exact same JSON response we saw in GraphiQL logged in the console. To get that displayed on the page we'll make use of React.useState() changing the code to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;GraphQLAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;authMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GRAPHQL_AUTH_MODE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;setTodos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;fetchTodos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've now got the list of todos in state, we just need to map over the array in JSX. Remove the four anchor tag sections and replace with the following code which will map over the todo array and display all our todos on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;{styles.grid}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {todos?.listTodos?.items.map((todo) =&amp;gt; {
      return (
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;{styles.card}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;{todo.name}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{todo.description}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      )
    })}
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the todo items you added in GraphiQL on the web page. This is good but it's all still JavaScript, we still need to add some TypeScript to make use of the GraphQL types. &lt;/p&gt;

&lt;p&gt;We can modify the GraphQLAPI code to use the generated &lt;code&gt;ListTodosQuery&lt;/code&gt; type from &lt;code&gt;API.ts&lt;/code&gt;. First import it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { listTodos, ListTodosQuery } from '../graphql'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then tell GraphQL to use this type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;GraphQLAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;authMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GRAPHQL_AUTH_MODE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ListTodosQuery&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how we need to account for the fact the response returned is a data object. If you look in the &lt;code&gt;API.ts&lt;/code&gt; file you'll see that the type doesn't contain a data object so we need to let TypeScript know that we expect it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ListTodosQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;__typename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ModelTodoConnection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;__typename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;nextToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you try typing a period &lt;code&gt;.&lt;/code&gt; after response in the console.log you'll see we now have full intellisense! TypeScript is telling you it expects the response to have a &lt;code&gt;data&lt;/code&gt; object. If you select that then type another period TypeScript tells you it expects a &lt;code&gt;listTodos&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;TypeScript now knows exactly what format our GraphQL API responses should be. However, down in the JSX code we've some more work to do. At the moment our API response is TypeScript aware but the JSX isn't, when mapping over the todos TypeScript can't infer what the types should be.&lt;/p&gt;

&lt;p&gt;We can fix that by telling React.useState what types to expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ListTodosQuery&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we've told TypeScript the same as the API to expect &lt;code&gt;ListTodosQuery&lt;/code&gt; as the type but also that it could be undefined if we don't yet have any data.&lt;/p&gt;

&lt;p&gt;Now if you go to the JSX and start typing you'll see all the same lovely intellisense!&lt;/p&gt;

&lt;p&gt;e.g. &lt;code&gt;{todo.name}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is great but if you take a closer look at the intellisense in VSCode you'll see some &lt;code&gt;__typename&lt;/code&gt; entries. Looking back at the &lt;code&gt;ListTodosQuery&lt;/code&gt; you note how that is indeed part of the type, but it's not data that we desire when working in React, in fact it's going to cause you problems further down the line. We can clean it up though.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript Omit &amp;amp; Exclude
&lt;/h2&gt;

&lt;p&gt;Fortunately we can automate this clean up in a nice way that won't break as we amend our &lt;code&gt;graphql.schema&lt;/code&gt; file by using TypeScripts Utility types &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys"&gt;Omit&lt;/a&gt; &amp;amp; &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion"&gt;Exclude&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a new file &lt;code&gt;graphql/APITypes.ts&lt;/code&gt; and add the export to your &lt;code&gt;graphql/index.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Next create a new file &lt;code&gt;graphql/DeepOmit.ts&lt;/code&gt; and paste in the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Primitive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DeepOmitArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;DeepOmit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DeepOmit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Primitive&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;TP&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;TP&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Primitive&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;TP&lt;/span&gt; &lt;span class="c1"&gt;// leave primitives and functions alone&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TP&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;DeepOmitArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// Array special handling&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DeepOmit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Stricly speaking DeepOmit isn't necessary in this example, you could just use Omit, however, when your schema becomes more complicated you may find DeepOmit will serve you better.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Back in &lt;code&gt;APITypes.ts&lt;/code&gt; we'll import DeepOmit and our Amplify generated types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DeepOmit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./DeepOmit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ListTodosQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./API&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now create base types from the generated Amplify types filtering out the &lt;code&gt;null&lt;/code&gt; entries and &lt;code&gt;__typename&lt;/code&gt; properties. The following code does just that for the generated &lt;code&gt;GetTodoQuery&lt;/code&gt; creating a new type named &lt;code&gt;TodoType&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TodoType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;DeepOmit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="nx"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GetTodoQuery&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getTodo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;__typename&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a type as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TodoType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make use of the type in React, import it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;listTodos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ListTodosQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TodoType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and update the JSX telling TypeScript that each todo item is of the TodoType:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;{styles.grid}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {todos?.listTodos?.items.map((todo: TodoType) =&amp;gt; {
      return (
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;{styles.card}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;{todo.name}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Find in-depth information about Next.js features and API.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      )
    })}
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Intellisense now works without the erroeneous &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;__typename&lt;/code&gt; properties.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing Schema
&lt;/h2&gt;

&lt;p&gt;So what happens when we extend our &lt;code&gt;schema.graphql&lt;/code&gt; file? Let's find out.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;schema.graphl&lt;/code&gt; add a completed flag, so the schema becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
  &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are still running &lt;code&gt;amplify mock&lt;/code&gt; then you'll notice something neat, the code generation updates automatically as soon as you save the file. If you look in &lt;code&gt;API.ts&lt;/code&gt; you see the new completed boolean in the type definitions.&lt;/p&gt;

&lt;p&gt;What about &lt;code&gt;APITypes.ts&lt;/code&gt;? Well that file hasn't been updated but it doesn't need to. It just pulls in the updated types from &lt;code&gt;API.ts&lt;/code&gt; and removes &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;__typename&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's try this out, back in our React code lets add the status of the completed flag in our UI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Status: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When adding the status and typing the period you should have noticed how TypeScript suggested completed as an option!&lt;/p&gt;

&lt;p&gt;If you look in the browser though you'll see status is null because we haven't set any value yet for the completed status and null is an appropriate alternative value. Let's fix that in GraphiQL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt; &lt;span class="nx"&gt;MyMutation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;updateTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8bce419d-39d5-425b-ab45-00f731e0454e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sorted!&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Our app now has a nice contract between the backend and the frontend using the &lt;code&gt;GraphQL.schema&lt;/code&gt; file as the glue and delivers on the promise of preventing runtime errors for both backend and frontend.&lt;/p&gt;




&lt;h3&gt;
  
  
  Inspiration
&lt;/h3&gt;

&lt;p&gt;This walkthrough is based on the groundwork of these excellent articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mwarger/aws-amplify-graphql-queries-with-typescript-and-hooks-1e2"&gt;https://dev.to/mwarger/aws-amplify-graphql-queries-with-typescript-and-hooks-1e2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/stevelizcano/5-minute-tutorial-get-base-types-from-your-aws-amplify-graphql-schema-with-typescript-3636"&gt;https://dev.to/stevelizcano/5-minute-tutorial-get-base-types-from-your-aws-amplify-graphql-schema-with-typescript-3636&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>amplify</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Multiple frontends with Amplify Console</title>
      <dc:creator>Dave Hudson</dc:creator>
      <pubDate>Sat, 30 May 2020 11:55:36 +0000</pubDate>
      <link>https://dev.to/applification/multiple-frontends-with-amplify-console-3nnj</link>
      <guid>https://dev.to/applification/multiple-frontends-with-amplify-console-3nnj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If you have an Amplify Console app with a cloud backend and need to connect a second app to it, this is the tutorial for you. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AWS Amplify is a fantastic solution for building secure, scalable full stack applications. The concept is that as you build out your frontend app, you also scaffold out your backend in the cloud using the Amplify CLI, storing the resulting config in a single Git repository. Amplify Console then provides a Git-based workflow for deploying and hosting your fullstack serverless app.&lt;/p&gt;

&lt;p&gt;The Amplify documentation covers this scenario in detail. What if you want to connect more than one app to your backend though? The schema for all of your cloud backend is in the first repo. How do you connect to say an iOS app, Android app or as in my case another React app to the cloud backend? &lt;/p&gt;

&lt;p&gt;The Amplify team have provided the basic commands to enable you to achieve this but the documentation and use cases are lagging, leaving you to search out the specifics yourself.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting a second app
&lt;/h2&gt;

&lt;p&gt;I'll assume you've already created your full-stack app in Amplify Console with a frontend web app and a cloud backend app. Now you want to get cracking on that second app and get it talking to your single backend.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you haven't you best start with the Getting Started Amplify Docs &lt;a href="https://docs.amplify.aws/start/q/integration/js" rel="noopener noreferrer"&gt;https://docs.amplify.aws/start/q/integration/js&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Scaffold out your app
&lt;/h3&gt;

&lt;p&gt;In my case I'm creating a Gatsby app so I ran the command &lt;code&gt;gatsby new gatsby-site&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pull down the backend
&lt;/h3&gt;

&lt;p&gt;Next you need to pull down the backend from Amplify. In Amplify Console select your app, select the &lt;code&gt;Backend environements&lt;/code&gt; tab and click the &lt;code&gt;Edit backend&lt;/code&gt; link. This will reveal the command you need to run in order to pull down the backend. In my case &lt;code&gt;amplify pull --appId dt9kkffvqgojy --envName dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fexmw5f5gizg6cjpjc602.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fexmw5f5gizg6cjpjc602.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run this command and follow the prompts as normal but for the final question "Do you plan on modifying this backend?" answer no. This ensures the &lt;code&gt;amplify&lt;/code&gt; folder is not copied to your second app. Whilst the docs say things will work if you have the amplify folder in your second app, it can lead to conflicts when pushing code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use Default
Amplify AppID found: dt9kkffvqgojy. Amplify App name is: test-app
Backend environment dev found &lt;span class="k"&gt;in &lt;/span&gt;Amplify Console app: test-app
? Choose your default editor: Visual Studio Code
? Choose the &lt;span class="nb"&gt;type &lt;/span&gt;of app that you&lt;span class="s1"&gt;'re building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start

? Do you plan on modifying this backend? No

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Download backend schema
&lt;/h3&gt;

&lt;p&gt;Most likely you'll also have a schema for your backend that you need to work with in your second app e.g if you've created an API. You'll need to also download that. &lt;/p&gt;

&lt;p&gt;Jump back into the Amplify Console and click on your backend environment name, in my case it is &lt;code&gt;Dev&lt;/code&gt; and click on the &lt;code&gt;API&lt;/code&gt; tab. I have a GraphQL API so I clicked the &lt;code&gt;View in AppSync&lt;/code&gt; button which opens the AppSync console. Click the &lt;code&gt;Schema&lt;/code&gt; navigation link and then the &lt;code&gt;Export schema&lt;/code&gt; button. Select the &lt;code&gt;schema.json&lt;/code&gt; option and save it in the root of your second app. &lt;/p&gt;

&lt;p&gt;You will now be able to run &lt;code&gt;amplify codegen add&lt;/code&gt; to configure your second project with your API to generate the GraphQL mutations, queries and subscriptions so your second app can talk to your amplify backend.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more information on codgen see the docs &lt;a href="https://docs.amplify.aws/cli/graphql-transformer/codegen" rel="noopener noreferrer"&gt;https://docs.amplify.aws/cli/graphql-transformer/codegen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this point you have everything you need to develop locally on your second app. If you need to work with a different environment, simply run the &lt;code&gt;amplify pull&lt;/code&gt;command, update &lt;code&gt;schema.json&lt;/code&gt;  and run the &lt;code&gt;amplify codegen&lt;/code&gt; command again. &lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring C.I builds
&lt;/h2&gt;

&lt;p&gt;Working in development locally is only part of the solution. As you move closer towards deployment you'll notice some issues. Specifically: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can't use your AWS Profile in continuous integration like you do on your local machine&lt;/li&gt;
&lt;li&gt;The interactive prompts from the &lt;code&gt;amplify pull&lt;/code&gt; command need to be automatically answered somehow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The solution to these problems is that you need to run the commands in headless mode &lt;a href="https://docs.amplify.aws/cli/usage/headless" rel="noopener noreferrer"&gt;https://docs.amplify.aws/cli/usage/headless&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update @amplify/cli in C.I
&lt;/h3&gt;

&lt;p&gt;Amplify pull is a relatively new command, so older versions of the Amplify CLI have no clue what to do when you run the command. So step 1 before you do anything else and to help you avoid losing many an hour to this quirk as I did, update the Amplify CLI in C.I. &lt;/p&gt;

&lt;p&gt;For some reason the default version of the Amplify CLI running in C.I of the Amplify Console is &lt;code&gt;1.12.0&lt;/code&gt;, the latest version being &lt;code&gt;4.21.0&lt;/code&gt;. To fix this go into the &lt;code&gt;Build settings&lt;/code&gt; section of the Amplify console for your project (available in the sidebar menu). Scroll to the bottom and edit the &lt;code&gt;Build image settings&lt;/code&gt;, then choose to &lt;code&gt;Add package version override&lt;/code&gt;. Select Amplify CLI and set the version to &lt;code&gt;canary&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgtxzx7aji75qdmqo2ef0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgtxzx7aji75qdmqo2ef0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will update &lt;code&gt;@amplify/cli&lt;/code&gt; during the &lt;code&gt;Cloning repository&lt;/code&gt; stage of your build to the latest version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;2020-05-28T12:51:32.924Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: &lt;span class="c"&gt;# Ensuring NPM package '@aws-amplify/cli' is version: 'canary'&lt;/span&gt;
2020-05-28T12:51:40.174Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: &lt;span class="c"&gt;# Patching NPM package '@aws-amplify/cli' from 1.12.0 to canary...&lt;/span&gt;
2020-05-28T12:52:45.411Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: &lt;span class="c"&gt;# Done patching NPM package '@aws-amplify/cli'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Headless Amplify pull
&lt;/h3&gt;

&lt;p&gt;Now that Amplify Console can understand the &lt;code&gt;amplify pull&lt;/code&gt; command we can run it in headless mode by passing the &lt;code&gt;--yes&lt;/code&gt; flag at the end. This means we don't get any of the question prompts and instead need to provide all of the parameters to the command. &lt;/p&gt;

&lt;p&gt;At the bottom of the documentation on headless CLI usage there is a section on &lt;code&gt;amplify pull&lt;/code&gt; that provides an example bash script. We'll use that as the basis for our C.I build. &lt;/p&gt;

&lt;p&gt;In the root of your project create a bash file named &lt;code&gt;amplify-pull.sh&lt;/code&gt; (can be named whatever you want). Then set execute permissions by running  &lt;code&gt;chmod u+x amplify-pull.sh&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  YAML configuration
&lt;/h3&gt;

&lt;p&gt;Next we need to make a few amends to the build config in Amplify Console to call our bash script. &lt;/p&gt;

&lt;p&gt;In the build settings edit the &lt;code&gt;amplify.yml&lt;/code&gt; file (you can also download it and put it in the root of your project if you prefer). In the frontend phase of the build we need to tell Amplify Console to run our bash script in the preBuild stage, e.g&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;
&lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;preBuild&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./amplify-pull.sh "${ACCESS_KEY_ID}" "${SECRET_ACCESS_KEY}" "${AWS_BRANCH}"&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above we specify that we want to run the command &lt;code&gt;./amplify-pull.sh&lt;/code&gt; which will pass everything over to our bash script. The bash script requires a number of environment variables which you'll note we also pass in via the YAML file. They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ACCESS_KEY_ID&lt;/li&gt;
&lt;li&gt;SECRET_ACCESS_KEY&lt;/li&gt;
&lt;li&gt;AWS_BRANCH (not strictly required but handy)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll need to set up these environment variable values within the Amplify Console. You'll find the values in your &lt;code&gt;.aws/credentials&lt;/code&gt; file on your local machine. These are the credentials you may have set up when running &lt;code&gt;amplify configure&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;See docs on setting environment variables in Amplify Console &lt;a href="https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The bash file
&lt;/h3&gt;

&lt;p&gt;Finally back to the empty bash file we created. The exact config of your bash file will depend on your specific needs. In my case I'm building a Gatsby site so the &lt;code&gt;DistributionDir&lt;/code&gt; is set to &lt;code&gt;public&lt;/code&gt; as that is where Gatsby likes to place the files when building for production. On the whole though the bash files should be fairly similar. &lt;/p&gt;

&lt;p&gt;It's important to know that environment variables are read in a bash script based on the order they are passed in. So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ACCESS_KEY_ID was passed in first so is available as $1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SECRET_ACCESS_KEY as $2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS_BRANCH as $3&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first part of the code checks $3 to check the current Git branch. This enables deploying different backends depending on which branch you are on with the value simply passed on as the $AWSENV variable to the Amplify object. Also note that &lt;code&gt;projectName&lt;/code&gt; and &lt;code&gt;appId&lt;/code&gt; are the values of the Amplify app in the other project that is fully connected to Amplify.&lt;/p&gt;

&lt;p&gt;The rest of the code is essentially the same as the example in the documentation but note that &lt;code&gt;accessKeyId&lt;/code&gt; and &lt;code&gt;secretAccessKey&lt;/code&gt; take their values from the environment variables we passed in.&lt;/p&gt;

&lt;p&gt;One additional step added is the &lt;code&gt;amplify codegen&lt;/code&gt; command, not stricly necessary as we did that locally but it does ensure the correct code is deployed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'|'&lt;/span&gt;

&lt;span class="c"&gt;# Use AWS_BRANCH var to check which backend to pull&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;AWSENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"prod"&lt;/span&gt; 
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nv"&gt;AWSENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"qa"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;REACTCONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;SourceDir&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;src&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;DistributionDir&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;public&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;BuildCommand&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;npm run-script build&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;StartCommand&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;npm run-script start&lt;/span&gt;&lt;span class="se"&gt;\"\&lt;/span&gt;&lt;span class="s2"&gt;
}"&lt;/span&gt;

&lt;span class="nv"&gt;AWSCLOUDFORMATIONCONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;configLevel&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;project&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;useProfile&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:false,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;profileName&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;accessKeyId&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;secretAccessKey&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;region&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;eu-west-2&lt;/span&gt;&lt;span class="se"&gt;\"\&lt;/span&gt;&lt;span class="s2"&gt;
}"&lt;/span&gt;

&lt;span class="nv"&gt;AMPLIFY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;projectName&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;admin-app&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;appId&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;dt9kkffvqgojy&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;envName&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$AWSENV&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;defaultEditor&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;code&lt;/span&gt;&lt;span class="se"&gt;\"\&lt;/span&gt;&lt;span class="s2"&gt;
}"&lt;/span&gt;

&lt;span class="nv"&gt;FRONTEND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;frontend&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;javascript&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;framework&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;config&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$REACTCONFIG&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
}"&lt;/span&gt;

&lt;span class="nv"&gt;PROVIDERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;awscloudformation&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$AWSCLOUDFORMATIONCONFIG&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
}"&lt;/span&gt;

amplify pull &lt;span class="nt"&gt;--amplify&lt;/span&gt; &lt;span class="nv"&gt;$AMPLIFY&lt;/span&gt; &lt;span class="nt"&gt;--frontend&lt;/span&gt; &lt;span class="nv"&gt;$FRONTEND&lt;/span&gt; &lt;span class="nt"&gt;--providers&lt;/span&gt; &lt;span class="nv"&gt;$PROVIDERS&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
amplify codegen

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! You should now be able to develop and publish your second app via continuous integration connected to the amplify cloud backend from your main app codebase. &lt;/p&gt;

&lt;p&gt;In truth it isn't that hard to set up, it is just that none of this is fully documented as yet and pitfalls like the outdated Amplify CLI in Amplify Console may prevent you knowing this is even possible at all. &lt;/p&gt;

</description>
      <category>aws</category>
      <category>amplify</category>
      <category>react</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
