我们将使用AWS Amplify和Vue来轻松创建一个聊天应用!!
AWS Amplify很好用,大家都在使用吗?
通过使用Amplify,我们可以将AWS的各种功能集成到SPA Web应用程序中,我们在这里尝试创建一个简单的基于DynamoDB + GraphQL数据源的聊天应用。
通过执行amplify命令,您可以感受到在不直接操作AWS管理控制台等的情况下创建一个相当完整的应用程序。
顺便说一下,这是 AWS Amplify Advent Calendar 2019 第14天的文章!
关于开发环境
$ vue -V
3.11.0
$ amplify -v
1.7.3
制作Vue应用程序
vue create vue-chat-app
Vue CLI v4.1.1
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
Manually select features
那我先试着启动一下看看。
cd vue-chat-app
yarn serve
http://本地主机:8081
创建一个Vue应用
首先,在没有集成Amplify的情况下,我们将创建一个Vue应用程序,以便能够简单地确认其行为。
引导程序的内置
您会使用Bootstrap-Vue处理UI部分,对吗?
$ yarn add bootstrap-vue bootstrap core-js
应用程序的实施
展开消息发送对话框
↓
在表格中输入
↓
显示消息
我会尽量在没有更新数据库的情况下实现到可行程度。
主要文件为src/main.js。
import Vue from 'vue'
import App from './App.vue'
import BootstrapVue from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
src/App.vue 的中文翻译:主文件/App.vue
<template>
<div id="app">
<header>
<b-navbar variant="info" type="dark">
<b-navbar-brand href="#">Vue Chat App</b-navbar-brand>
<b-navbar-nav class="ml-auto">
<b-nav-form>
<b-button @click="modalShow = !modalShow" variant="light">Post</b-button>
</b-nav-form>
</b-navbar-nav>
</b-navbar>
</header>
<b-container>
<section class="form">
<section>
<b-modal v-model="modalShow" size="lg" title="Post chat message">
<section v-if="errors.length > 0" class="alerts">
<div
v-for="(error, j) in errors"
v-bind:key="j"
class="alert alert-danger"
role="alert"
>{{ error }}</div>
</section>
<b-form>
<b-form-group label="User:" label-for="user">
<b-form-input id="user" v-model="form.user" required placeholder="Enter user"></b-form-input>
</b-form-group>
<b-form-group label="message" label-for="message">
<b-form-textarea
id="message"
v-model="form.message"
placeholder="Enter something..."
rows="3"
max-rows="6"
></b-form-textarea>
</b-form-group>
</b-form>
<template v-slot:modal-footer="{ submit, cancel, close }">
<b-button variant="success" @click="onPostMessage">Submit</b-button>
<b-button variant="default" @click="onCancel">Cancel</b-button>
</template>
</b-modal>
</section>
<section>
<b-card
v-for="(chat, i) in chats"
v-bind:key="i"
v-bind:footer="chat.user + ' - ' + chat.created_at"
footer-tag="footer"
>
<b-media>
<template v-slot:aside>
<b-img width="64" src="https://picsum.photos/200"></b-img>
</template>
{{ chat.message }}
</b-media>
</b-card>
</section>
</section>
</b-container>
</div>
</template>
<script>
export default {
user: "app",
data() {
return {
form: {
user: "",
message: ""
},
chats: [],
modalShow: false,
errors: []
};
},
computed: {
formIsInValid() {
return this.errors.length > 0;
},
chatParams() {
return {
...this.form,
created_at: new Date().toLocaleString()
};
}
},
methods: {
onPostMessage() {
this.checkMessageParams();
if (this.formIsInValid) {
return;
}
this.postMessage();
this.modalShow = false;
this.form.user = "";
this.form.message = "";
},
postMessage() {
this.chats.push(
this.chatParams
)
},
onCancel() {
this.modalShow = false;
},
checkMessageParams() {
this.errors = [];
if (this.form.user === "") {
this.errors.push('"User" is required.');
}
if (this.form.message === "") {
this.errors.push('"message" is required.');
}
}
}
};
</script>
<style>
.card {
margin: 1em 0;
}
</style>
3. 将Amplify集成进去 Amplify
3.1 初始化
毫不猶豫地打出以下的指令。
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project
vue-chat-app
? Enter a name for the environment
develop
? 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:
yarn build
? Start Command:
yarn serve
3.2 将托管至 S3
尽管顺序无所谓,但在进行数据库周围的设置之前,本次将把当前状态的应用程序部署到S3。
$ amplify add hosting
? Select the environment setup: (S3 only with HTTP)
DEV
? hosting bucket name
vue-chat-app-20191214083130-hostingbucket
? index doc for the website
index.html
? error doc for the website
index.html
You can now publish your app using the following command:
Command: amplify publish
$ amplify publish
Current Environment: develop
| Category | Resource name | Operation | Provider plugin |
| -------- | --------------- | --------- | ----------------- |
| Hosting | S3AndCloudFront | Create | awscloudformation |
? Are you sure you want to continue?
Yes
~
✨ Done in 35.82s.
frontend build command exited with code 0
✔ Uploaded files successfully.
Your app is published successfully.
http://vue-chat-app-20191214083130-hostingbucket-develop.s3-website-ap-northeast-1.amazonaws.com
执行publish命令后,将执行在amplify init命令行中回答的构建命令(yarn build),并将其部署到S3中。
部署完成后,将显示S3终端点地址,请尝试访问。
请将以下内容以中文本地化重述,只需一种选项:
http://vue-chat-app-20191214083130-hostingbucket-develop.s3-website-ap-northeast-1.amazonaws.com
http://vue-chat-app-20191214083130-hostingbucket-develop.s3-website-ap-northeast-1.amazonaws.com网址。
如果显示的应用程序与本地确认的一样,那就可以了。
新增了3.3 API。
$ amplify add api
? Please select from one of the below mentioned services
GraphQL
? Provide API name:
vuechatapp
? Choose an authorization type for the API
API key
? Do you have an annotated GraphQL schema?
No
? Do you want a guided schema creation?
Yes
? What best describes your project: (e.g., “Todo” with ID, name, description)
Single object with fields
? Do you want to edit the schema now?
Yes
Please edit the file in your editor: /Users/Work/aws_amplify/vue-chat-app/amplify/backend/api/vuechatapp/schema.graphql
s? Press enter to continue
选择“是”将启动编辑器,并显示如下所示的GraphQL模式文件模板。
GraphQL架构
type Todo @model {
id: ID!
name: String!
description: String
}
将进行如下更改。
type Chat @model {
id: ID!
user: String!
message: String
created_at: String
}
我会试着放大状况来看。
$ amplify status
Current Environment: develop
| Category | Resource name | Operation | Provider plugin |
| -------- | --------------- | --------- | ----------------- |
| Api | vuechatapp | Create | awscloudformation |
| Hosting | S3AndCloudFront | No Change | awscloudformation |
Hosting endpoint: http://vue-chat-app-20191214083130-hostingbucket-develop.s3-website-ap-northeast-1.amazonaws.com
所以,我们将重新部署。
由于是在API端创建资源,所以这次我们会进行推送。
推送操作是将在本地修改的Amplify更改应用到AWS上,
发布操作则是在Amplify更改的基础上进行应用构建和部署操作。
"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
当您进行Amplify push操作时,会显示一些问题。
以下所有内容均为默认值。
GraphQL schema compiled successfully.
Edit your schema at /Users/yuto-ogi/Work/aws_amplify/vue-chat-app/amplify/backend/api/vuechatapp/schema.graphql or place .graphql files in a directory at /Users/yuto-ogi/Work/aws_amplify/vue-chat-app/amplify/backend/api/vuechatapp/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...
当在AWS上创建GrapyQL资源完成后,将在源目录中创建如下文件。
modified: .graphqlconfig.yml
modified: src/graphql/mutations.js
modified: src/graphql/queries.js
modified: src/graphql/schema.json
modified: src/graphql/subscriptions.js
此外,在src文件夹下会创建aws-exports.js文件(该文件包含认证信息,应将其加入.gitignore)。
然后,在Vue应用程序中加载该文件。
const awsmobile = {
"aws_project_region": "ap-northeast-1",
"aws_content_delivery_bucket": "*********************************",
"aws_content_delivery_bucket_region": "ap-northeast-1",
"aws_content_delivery_url": "*********************************",
"aws_appsync_graphqlEndpoint": "*********************************",
"aws_appsync_region": "ap-northeast-1",
"aws_appsync_authenticationType": "API_KEY",
"aws_appsync_apiKey": "*********************************"
};
export default awsmobile;
3.4 将AppSync集成到Vue应用程序中
$ yarn add aws-amplify aws-amplify-vue
我会在下面增补内容。
主要.js
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)
Vue.config.productionTip = false
App.vue 的中文释义是:应用视图组件。
在使用amplify push之后,将创建的与GraphQL相关的文件导入并集成到应用程序中。
import { API, graphqlOperation } from "aws-amplify";
import { createChat } from "@/graphql/mutations";
import { listChats } from "@/graphql/queries";
import { onCreateChat } from "@/graphql/subscriptions";
在created动作中,我们执行了两个操作:加载现有记录并订阅对数据库的更改。
async created() {
// query
const queryResponse = await API.graphql(graphqlOperation(listChats));
this.chats = queryResponse.data.listChats.items;
// subscribe
API.graphql(
graphqlOperation(onCreateChat)
).subscribe({
next: chat => {
this.chats.push(chat.value.data.onCreateChat);
}
});
},
通过postMessage,使用GraphQL的mutation功能在DynamoDB中创建记录。
async postMessage() {
await API.graphql(
graphqlOperation(createChat, {
input: this.chatParams
})
).catch(error => {
console.error(error);
});
},
4. 暴露
完成本地测试后,将其部署到S3。
$ amplify publish
我們使用了Lorem Picsum在用戶圖標中顯示圖像,但我們只是暫時指定了一個鏈接,因此每次重新加載頁面時圖像都會變化,並且所有用戶都會看到相同的圖像^^;
最後
这个应用程序是在Hamamatsu.js #8的实践中使用的。遗憾的是,当天我们没有实现Amplify的嵌入,希望这个Advent日历能成为一种供奉。
请查看这里的最终源代码,如果方便的话。
杰克优旅斯/Vue聊天应用