AWS Amplify Subscriptions Usage / 1. Open Chat
Tags: aws, amplify, vue, graphql
Published: 2021-01-10 12:06:27

We can use the Subscriptions feature with AWS Amplify.
It's easy for us to get started, but it can be complicated.

In this article, I'll show you a simple way to use Subscriptions by `Chat` application.

My repository:
{% github tacck/sample-amplify-subscriptions no-readme %}

## Setup

Please see these amplify documents.

- https://docs.amplify.aws/cli/start/install
- https://docs.amplify.aws/start/getting-started/installation/q/integration/vue
- https://docs.amplify.aws/start/getting-started/setup/q/integration/vue

Use Vue.js (and Vuetify) in this article.

```
% vue create sample-amplify-subscriptions
% cd sample-amplify-subscriptions
% vue add vuetify
% amplify init
% yarn add aws-amplify @aws-amplify/ui-vue
% amplify push
```

## Implementations

This is the first implementation.
Anyone can write messages and receive message immediately.

### Add API

Add API.

```
$ amplify add api
Initializing new Amplify CLI version...
Done initializing new version.
Scanning for plugins...
Plugin scan successful
? Please select from one of the below mentioned services: GraphQL
? Provide API name: sampleamplifysubscri
? Choose the default authorization type for the API API key
? Enter a description for the API key: 
? After how many days from now the API key should expire (1-365): 365
? Do you want to configure advanced settings for the GraphQL API No, I am done.
? Do you have an annotated GraphQL schema? No
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)

The following types do not have '@auth' enabled. Consider using @auth with @model
         - Todo
Learn more about @auth here: https://docs.amplify.aws/cli/graphql-transformer/directives#auth


GraphQL schema compiled successfully.

Edit your schema at /[YOUR_DIRECTORY]/sample-amplify-subscriptions/amplify/backend/api/sampleamplifysubscri/schema.graphql or place .graphql files in a directory at /[YOUR_DIRECTORY]/sample-amplify-subscriptions/amplify/backend/api/sampleamplifysubscri/schema
? Do you want to edit the schema now? No
Successfully added resource sampleamplifysubscri locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

$
```

Edit GraphQL scheme file.
(`amplify/backend/api/sampleamplifysubscri/schema.graphql`)

``` graphql
type OpenChat @model {
  id: ID!
  message: String!
}
```

And, push project.

```
$ amplify push
Initializing new Amplify CLI version...
Done initializing new version.
Scanning for plugins...
Plugin scan successful
✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category | Resource name        | Operation | Provider plugin   |
| -------- | -------------------- | --------- | ----------------- |
| Api      | sampleamplifysubscri | Create    | awscloudformation |

Tag Changes Detected
? Are you sure you want to continue? Yes

The following types do not have '@auth' enabled. Consider using @auth with @model
         - OpenChat
Learn more about @auth here: https://docs.amplify.aws/cli/graphql-transformer/auth


GraphQL schema compiled successfully.

Edit your schema at /[YOUR_DIRECTORY]/sample-amplify-subscriptions/amplify/backend/api/sampleamplifysubscri/schema.graphql or place .graphql files in a directory at /[YOUR_DIRECTORY]/sample-amplify-subscriptions/amplify/backend/api/sampleamplifysubscri/schema
? 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
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
⠸ Updating resources in the cloud. This may take a few minutes...

(snip)

✔ Generated GraphQL operations successfully and saved at src/graphql
✔ All resources are updated in the cloud

GraphQL endpoint: https://XXXXXXXXXXXXXXXXXXXXXXXXXX.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

$
```

### Write Open Chat

`src/views/OpenChat.vue` :

``` vue
<template>
  <v-container>
    <v-row>
      <v-col cols="12">
        <v-card>
          <v-card-title>Open Chat</v-card-title>
          <v-card-text
            >Anyone can use this chat. All subscriptions are
            receved.</v-card-text
          >
        </v-card>
      </v-col>
    </v-row>
    <v-row>
      <v-col cols="12">
        <v-text-field
          v-model="inputMessage"
          label="New Message"
          outlined
          clearable
          append-outer-icon="mdi-send"
          @click:append-outer="sendMessage"
        ></v-text-field>
      </v-col>
    </v-row>
    <v-row>
      <v-col cols="6">
        <ChatList title="Input" :list="messages"></ChatList>
      </v-col>
      <v-col cols="6">
        <ChatList title="Subscriptions" :list="subscriptionMessages"></ChatList>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import { API, graphqlOperation } from 'aws-amplify'
import { createOpenChat } from '@/graphql/mutations'
import { onCreateOpenChat } from '@/graphql/subscriptions'

import ChatList from '@/components/ChatList'

export default {
  components: { ChatList },
  data: function() {
    return {
      inputMessage: '',
      onCreateOpenChatSubscription: null,
      messages: [],
      subscriptionMessages: [],
    }
  },
  created: function() {
    this.onCreateOpenChatSubscription = API.graphql(
      graphqlOperation(onCreateOpenChat),
    ).subscribe({
      next: ({ provider, value }) => {
        console.log({ provider, value })
        this.subscriptionMessages.push(value.data.onCreateOpenChat)
      },
    })
  },
  beforeDestroy: function() {
    if (this.onCreateOpenChatSubscription) {
      this.onCreateOpenChatSubscription.unsubscribe()
      this.onCreateOpenChatSubscription = null
    }
  },
  methods: {
    sendMessage: async function() {
      const message = await API.graphql(
        graphqlOperation(createOpenChat, {
          input: { message: this.inputMessage },
        }),
      )
      console.log(message)

      this.messages.push(message.data.createOpenChat)
      this.inputMessage = ''
    },
  },
}
</script>

<style></style>
```

See other files :
https://github.com/tacck/sample-amplify-subscriptions/tree/1-open-chat

The important point is here.

``` JavaScript
(snip)

  created: function() {
    this.onCreateOpenChatSubscription = API.graphql(
      graphqlOperation(onCreateOpenChat),
    ).subscribe({
      next: ({ provider, value }) => {
        console.log({ provider, value })
        this.subscriptionMessages.push(value.data.onCreateOpenChat)
      },
    })
  },

(snip)
```

We can use subscription like above code.
It's very simple.

Next step, we will create some chat rooms and received each room's messages.