Getting Started With AWS Amplify - Part One - Initialize Amplify
Tags: javascript, tutorial, aws, amplify
Published: 2020-08-01 02:09:08

---
title: Getting Started With AWS Amplify - Part One - Initialize Amplify
published: true
description: In this 2+ part blog post series, I wanted to build a simple AMA type app. I think the app concept covers a handful of concepts that will help you learn a bit more about Amplify.
tags: javascript, tutorial, aws, amplify
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/d170y8hgg7fx9m9vzmb8.jpg
canonical_url: https://www.travis.codes/blog/getting-started-with-amplify-part-one/
---

*Originally posted on my personal blog here: [travis.codes](https://www.travis.codes/blog/getting-started-with-amplify-part-one/)*

I recently came across AWS Amplify and have really enjoyed playing around with it. I am trying to get better at blogging, and also wanted to teach myself more about Amplify, so this kills two birds with one stone.

In this 2+ part blog post series, I wanted to build a simple ~~Todo~~ AMA type app. I think the app concept covers a handful of concepts that will help you learn a bit more about Amplify.

Here is what we will be making:

![Screenshot of the demo app](https://www.travis.codes/static/7769536545cbed383f4834136474e591/c83ae/demo-screenshot.png)

In this first post, I wanted to dive into getting started with Amplify and playing around in the GraphiQL playground with our API. In the next post, we will build out the UI and add Authentication.

This is one of my first bigger technical type posts, so if you find any mistakes, please nicely let me know 😅

Alrighty, let’s do this!

## Install
First things first, let’s get all the things installed.

![install all the things meme](https://www.travis.codes/static/2b5124622a9aa9ed39b4dd4c7f29e4ee/1c72d/install-all-the-things.jpg)

```bash
npx create-react-app ama --use-npm
```

Install our dependencies
```bash
cd ama
npm install aws-amplify node-sass react-router react-router-dom @aws-amplify/ui-react
```

If you don’t already have the AWS Amplify CLI installed, do that now:  [Amplify Framework Documentation](https://docs.amplify.aws/cli/start/install#option-2-follow-the-instructions)

Let’s get Amplify initiated with `amplify init`
You will be given a list of questions to answer.

![image of terminal showing amplify init](https://www.travis.codes/static/26ced6af8760e3b2475c50f25ee96cd6/c83ae/amplify-init.png)
For the most part, I chose the default. For the code editor, I use VS Code, but if you use something else, be sure to pick that.
Since we are using javascript, we pick that
And we are using react
The defaults for the paths and commands are what we want.
Then say Yes to using an AWS profile and chose the profile you want.
After that, Amplify will start initializing the project in the cloud.

## Adding our API
We will be using the GraphQL Transform in order to get our backend set up quickly. We use the Schema Definition Language or SDL to model our data, and then the amplify converts our SDL into AWS CloudFormation templates for us, kind of like magic.

To get started just run `amplify add api`

Select `GraphQL`
Just use the default API name by pressing enter
For the default authorization, choose `API key` for now, we will revisit Auth in a future post.
Pick the defaults for the API key questions
Do you have an annotated GraphQL schema? `No`
Do you want a guided schema creation? `Yes`
What best describes your project? `One-to-many relationship`
Do you want to edit the schema now? `Yes`

All the questions and answers:
![image of terminal showing amplify add API](https://www.travis.codes/static/2d48dd4e393e15127cd30e11ac68f5e9/c83ae/amplify-add-api.png)

Your code editor should now be open with the following schema:
```graphql:title=schema.graphql
type Blog @model {
  id: ID!
  name: String!
  posts: [Post] @connection(keyName: "byBlog", fields: ["id"])
}

type Post @model @key(name: "byBlog", fields: ["blogID"]) {
  id: ID!
  title: String!
  blogID: ID!
  blog: Blog @connection(fields: ["blogID"])
  comments: [Comment] @connection(keyName: "byPost", fields: ["id"])
}

type Comment @model @key(name: "byPost", fields: ["postID", "content"]) {
  id: ID!
  postID: ID!
  post: Post @connection(fields: ["postID"])
  content: String!
}
```

We are going to replace all of it, but this gives us a good starting point.

Let’s walk through what the above means.
Each object type has a couple words with the @ symbol in front of them, these are called `directives` and are super helpful in creating our API.

As of right now, Amplify has 9 built in directives.
```
@model
@key
@auth
@function
@connection
@versioned
@searchable
@predictions
@http
```

In our example we are currently using `@model, @connection and @key` so let’s look into what those mean.

### @model
Object types with the `@model` directive are stored in DynamoDB, can be protected with the `@auth` directive and can be searchable with the `@searchable` directive.

According to the docs, here is what Amplify is doing for us just by using the `@model` directive 🤯:

* An Amazon DynamoDB table with PAY_PER_REQUEST billing mode enabled by default.
* An AWS AppSync DataSource configured to access the table above.
* An AWS IAM role attached to the DataSource that allows AWS AppSync to call the above table on your behalf.
* Up to 8 resolvers (create, update, delete, get, list, onCreate, onUpdate, onDelete) but this is configurable via the queries, mutations, and subscriptions arguments on the @model directive.
* Input objects for create, update, and delete mutations.
* Filter input objects that allow you to filter objects in list queries and connection fields.
* For list queries the default number of objects returned is 100. You can override this behavior by setting the **limit** argument.

### @connection
The connection directive allows you to set up relationships between `@model` types. It currently supports one-to-one, one-to-many and many-to-one relationships.

### @key
Makes it easy to configure custom index structures for `@model` types.
The `@key` directive has one required argument and two optional args

**Fields**
The list of fields that comprise the` @key`, used in conjunction with `@model` The first fields in the array will be the HASH key, if a second field is provided, it is used as the SORT key.

**Name**
If provided, the name provides the name of the secondary index.

**queryField**
This allows you to specify a new top level query that uses the secondary index, defined by setting the *name* argument.

For great examples and data patterns, check out [Amplify Framework Documentation](https://docs.amplify.aws/cli/graphql-transformer/directives#designing-data-models-using-key)


## User stories
Now that we know a little bit more about what our schema is doing, let’s start making our own schema, but first let’s create some user stories.

* Users can see a list of all questions
* Users can ask a new question
* A user can answer a question
* A user can delete a question

Now that we know what our app will be doing, let’s model out our data. Replace all of the generated Todo Schema and replace it with the following:

```graphql
type Question
  @model
  @key(
    name: "byDate"
    fields: ["type", "createdAt"]
    queryField: "questionsByDate"
  ) {
  id: ID!
  type: PostType!
  content: String
  createdAt: AWSDateTime!
  answer: Answer @connection(fields: ["id"])
}

type Answer
  @model
  @key(fields: ["questionID"])
 {
  id: ID!
  questionID: ID!
  content: String!
  createdAt: AWSDateTime!
}

enum PostType {
  QUESTION
}

```

The `@key` directive for the Question type, allows us to query our Questions by type, and then sort by createdAt
The `@connection` directive on the Question answer property, creates a relationship between the Question and the Answer models. Each Question can only have one Answer.
The `@key` directive on the Answer model creates a bi-directional one-to-one relationship with our Question.

Once you have it how we like it, save the file and go back to your terminal and press enter. It will most likely yell as you for not having the `@auth` directive on our models, but we will cover that in the next post.

This will generate our API, now we can do an `amplify push` to deploy it.

You’ll see a status of what resources have been created/updated, and then you can hit enter to continue.

![image of terminal showing amplify push status](https://www.travis.codes/static/f7f0839508ebcbe33bc39abbb9e58ab9/c83ae/amplify-push.png)

```bash
? Do you want to generate code for your newly created GraphQL API Yes
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/
**/*.js # default
? Do you want to generate/update all possible GraphQL operations - queries, mutations and
subscriptions Yes #default
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2 #default
```

> Alternately, you can run `amplify push -y` to answer **Yes** to all questions.

Once you go through the questions, you’ll see an `Updating resources in the cloud. This may take a few minutes...` message.

Wait a couple of minutes, and you should have your API deployed! 🎉

![Ron Swanson GIF](https://media.giphy.com/media/fdyZ3qI0GVZC0/giphy.gif)

### Testing our API
The Amplify CLI has a handy feature that allows us to mock our API, for testing locally. Just run `amplify mock api` It will spit out a url for you to use which will open a GraphiQL interface in which we can test at our API.

If you haven’t used GraphiQL before, it’s pretty straight forward. On the left-hand side you’ll see the queries that Amplify made for us. On the bottom of the left panel, you can switch between Query, Mutation, and Subscription.

![GraphiQL Interface](https://www.travis.codes/static/c887df6d7e4024fa6d514f247a25800a/c83ae/graphiql.png)

The main panel is split into two sections, the left side is where we write our queries, mutations, and subscriptions, and the right side is what gets returned. We also have a docs panel on the upper right we can open. This shows us all the available functions we have, the inputs, and more.

Let’s dive in and start playing around with our API.


#### createQuestion mutation
In order to get some data added in, let’s create our first question.
```graphql
mutation createQuestion {
  createQuestion(input: {
    content: "do you like bacon and eggs?"
    type: QUESTION
  }) {
    id
    content
  }
}
```
As you can see, we are returning the `id` from the newly created Question.

The data returned should look like this:

```graphql
{
  "data": {
    "createQuestion": {
      "id": "46bcc95a-4457-4dd6-b33a-e286ed049cf8",
      "content": "do you like bacon and eggs?"
    }
  }
}
```

We can add our `questionID` and our `answerContent` to our variables panel so we can answer a question in our GraphiQL playground. Once we do so, we can write our `createAnswer` mutation.

![image of GraphiQL playground query variables](https://www.travis.codes/static/fa20f3ec6f926fbc246911f58f59056e/c83ae/query-vars-2.png)

#### createAnswer mutation


```graphql
mutation createAnswer($questionID: ID!, $answerContent: String!) {
  createAnswer(input:{
    questionID: $questionID
    content: $answerContent
  }) {
    id
    content
  }
}
```

This will return data that looks like this:
```graphql
{
  "data": {
    "createAnswer": {
      "id": "c6ac3607-5995-4c55-80f3-e90d5a106a03",
      "content": "I do, and I will take all the bacon and eggs you have"
    }
  }
}
```

#### listQuestions query

To see if that all worked, lets do a query and list all the questions with their answer
```graphql
query listQuestions {
  listQuestions {
    items {
      id
      content
      answer {
        id
        content
      }
    }
  }
}
```

If you have only added the one question above, you should see something similar to this:
```graphql
{
  "data": {
    "listQuestions": {
      "items": [
        {
          "id": "3336596f-6e5a-488b-a0dd-6ebe1699cf54",
          "content": "do you like bacon and eggs?",
          "answer": {
            "id": "d456152a-e995-49ce-ab4f-2d28ba2dc99a",
            "content": "I do, and I will take all the bacon and eggs you have"
          }
        }
      ]
    }
  }
}
```

#### deleteQuestion mutation

One last thing, we should be able to delete a question.
```graphql
mutation deleteQuestion($questionID: ID!) {
  deleteQuestion(input: {id: $questionID}) {
    content
  }
}
```

This will delete the question with the passed `questionID`. To double check it worked, you can run the list questions query and it should return an empty items array.
```graphql
{
  "data": {
    "listQuestions": {
      "items": []
    }
  }
}
```

Whew, I think we made it! We got Amplify set up, we added a GraphQL API and then created some fake data using the GraphiQL playground.

In the next post, we will create the React app that will handle asking a question, answering a question.

👉 [Part Two](https://www.travis.codes/blog/getting-started-with-amplify-part-two/)

You can find the code here:
{% github werbelow/amplify-tutorial no-readme %}