AWS AmplifyとVue.jsでGraphQL形式のWebアプリを作る。
AWS Amplify触ってみる。GraphQL形式のapiとそれを使ったVueアプリがサラッと作れる。
今回は公式ドキュメントのチュートリアルを試す。
まずはvue cliでプロジェクトを作る。
vue create amplifytest
次にamplify cliのインストールと認証設定。
npm install -g @aws-amplify/cli
amplify configure
configureすると、ログインとか、IAMでルートユーザーを作らされる。途中でブラウザが開くので操作をして完了したら、コマンドに戻って進める。
次にvue cliで作ったプロジェクトに移動
cd amplifytest
ここからamplicy cliを使って、設定をしていく。まずプロジェクト全体のAWS Amplifyについての設定をする。
amplify init
プロジェクトのことを聞かれる。
Scanning for plugins...
Plugin scan successful
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project amplifytest
? Enter a name for the environment test
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using vue
? Source Directory Path: src
? Distribution Directory Path: dist
? Build Command: npm.cmd run-script build
? Start Command: npm.cmd run-script serve
Using default provider awscloudformation
For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use (Use arrow keys)
? Please choose the profile you want to use default
プロジェクトの名前とか、vueを使いますよとか設定していく。
API(Amplify)を使う。
次に、Amplifyで使う機能(API)の設定をしていく。
ここで使うのはAPIというのはモデル定義ファイルを書くだけで、バックエンドapiと、クライアントコードを作ってくれる。
以下のコマンドを打つ。
amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: amplifytest
? Choose the default authorization type for the API API key
? Enter a description for the API key: amplifytest
? After how many days from now the API key should expire (1-365): 7
? Do you want to configure advanced settings for the GraphQL API No, I am done.
? Do you have an annotated GraphQL schema? No
? Do you want a guided schema creation? Yes
? What best describes your project: (Use arrow keys)
> Single object with fields (e.g., “Todo” with ID, name, description)
? What best describes your project: Single object with fields (e.g., “Todo” with ID, name, description)
? Do you want to edit the schema now? No
クエリ形式にGraphQLを選び、認証方法をとりあえず7日間使えるAPI keyを選んだ。後からも変えられるようだ。
GraphQLスキーマ定義言語(SDL)で書かれたモデル定義ファイルというのがある。 今回は最初から用意されているTodoスキーマ定義をそのまま使う。
するとAPIの設定と、 Todoスキーマ定義 のファイルが作られる。定義ファイルは amplify/backend/api/YOUR-API-NAME/schema/
フォルダに.schema
という拡張子 でできている。
設定をして、定義ファイルを用意したので、今度は定義にしたがってawsにapiを作ってもらう。
amplify push
? 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
スキーマ定義からクライアント用のGraphQLコードを生成するかい?上書きするよ?といったことを聞かれる。yes.
すると色々やってくれる。バックエンド側は、AWSのAmazon DynamoDBと、AWS AppSyncというサービスで作られている。以下のコマンドでコンソールが開く。
amplify console api
クライアント用のコードも生成されている。基本的なCRUD操作のGraphQLクエリとtypescript型定義が src/graphql
フォルダに生成されている。
amplify mock api
Vue.jsからAmplifyする
よしバックエンド側はこれでできたので、次はVue.jsだ。まずVue用のAmplifyコンポーネントをインストールする。最近のサービスはこういうのも用意してくれているんだ。
npm i aws-amplify
npm i aws-amplify-vue
読み込むコードを書く。よくわからないからコピペだ。
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
Vue.config.productionTip = false;
// aws amplify
import Amplify, * as AmplifyModules from "aws-amplify";
import { AmplifyPlugin } from "aws-amplify-vue";
import awsconfig from "./aws-exports";
Amplify.configure(awsconfig);
Vue.use(AmplifyPlugin, AmplifyModules);
new Vue({
router,
render: h => h(App)
}).$mount("#app");
ここからAWS AmplifyのドキュメントのVueのページにあるコードを書いてみる。
今回作るのは、Todoを作成したら、画面に反映する。つまりcreate操作とsubscription操作を試す。 もしかすると複数ユーザーでも反映される。
説明は省くが以下のようになる。
<template>
<div class="home">
<amplify-connect
:query="listTodosQuery"
:subscription="createTodoSubscription"
:onSubscriptionMsg="onCreateTodo"
>
<template slot-scope="{loading, data, errors}">
<div v-if="loading">Loading...</div>
<div v-else-if="errors.length > 0">Error!</div>
<div v-else-if="data">
<ul>
<li v-for="item in data.listTodos.items" v-bind:key="item.id">
<span>{{item.id}} - {{item.name}} - {{item.description}}</span>
</li>
</ul>
</div>
</template>
</amplify-connect>
<amplify-connect :mutation="createTodoMutation" @done="onCreateFinished">
<template slot-scope="{ loading, mutate, errors }">
<div v-if="loading">Loading...</div>
<div v-else-if="errors.length > 0">Error!</div>
<input v-model="form.name" placeholder="item name" />
<input v-model="form.description" placeholder="item description" />
<button :disabled="loading" @click="mutate">Create Todo</button>
</template>
</amplify-connect>
</div>
</template>
<script>
const ListTodosQuery = `query ListTodos {
listTodos {
items {
id
name
description
}
}
}`;
const OnCreateTodoSubscription = `subscription OnCreateTodo {
onCreateTodo {
id
name
description
}
}`;
const CreateTodoMutation = `mutation CreateTodo($name: String!, $description: String) {
createTodo(input: { name: $name, description: $description }) {
id
name
description
}
}`;
export default {
name: "Home",
data() {
return {
form: { name: "", description: "" }
};
},
computed: {
listTodosQuery() {
return this.$Amplify.graphqlOperation(ListTodosQuery);
},
createTodoSubscription() {
return this.$Amplify.graphqlOperation(OnCreateTodoSubscription);
},
createTodoMutation() {
return this.$Amplify.graphqlOperation(CreateTodoMutation, {
name: this.form.name,
description: this.form.description
});
}
},
methods: {
onCreateTodo(prevData, newData) {
console.log("New todo from subscription...");
const newTodo = newData.onCreateTodo;
prevData.data.listTodos.items.push(newTodo);
return prevData.data;
},
onCreateFinished() {
console.log("Todo created!");
}
}
};
</script>
npm run serve
で確認できる。
というわけでできた。動くとテンション上がる。
スキーマ定義をしていけば、作りたいアプリのプロトタイプをどんどん作っていけそうなので、楽しみ。
ディスカッション
コメント一覧
まだ、コメントがありません