使用AWS Amplify和Nuxt,快速创建Web应用程序
由於有機會在AWS上開發Web應用程式,我進行了一些研究,發現Amplify似乎很方便,因此我試著使用了它。
本次创建的应用程序的主要功能如下:
-
- NuxtベースのTODOアプリ
-
- Lambda使ったGraphQLのAPI
-
- DynamoDBへのデータ保存/読込
-
- DynamoDBのデータとリアルタイム同期
- Cognitoによる認証機能
基本上,我們將按照官方教程的步驟進行操作,但由於在使用Nuxt時有一些變更點,希望這些變更對Nuxt的使用者有所幫助。
Amplify的初始设置
首先,让我们安装Amplify的CLI。
$ npm install -g @aws-amplify/cli
一旦安装完成,应该可以使用amplify命令。我会立即使用configure进行设置尝试。
$ amplify configure
Scanning for plugins...
Plugin scan successful
Follow these steps to set up access to your AWS account:
Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue
当出现类似的日志并要求登录 AWS 时,请进行登录。然后返回控制台。
回到之后,需要进行区域设置。如果在东京,应选择ap-northeast-X。用户名可以使用默认值,但为了方便理解,我选择了amplify-admin。
Specify the AWS Region
? region: ap-northeast-1
Specify the username of the new IAM user:
? user name: amplify-admin
Complete the user creation using the AWS console
https://console.aws.amazon.com/iam/home?region=undefined#/users$new?step=final&accessKey&userNames=amplify-admin&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess
Press Enter to continue
在这里,AWS控制台会在浏览器中打开,并要求添加用户。基本上,全部都可以使用默认设置。
我会继续前进到下一个画面。
我会保持现状并继续前进。
最后将显示以下画面,请不要关闭此页面。
我会返回控制台界面。
当你返回后,请根据显示在成功画面上的值输入密钥。请注意管理密钥以防泄露。配置文件名称可以是任意的,本次默认设置为”default”。
Enter the access key of the newly created user:
? accessKeyId: # 成功画面に表示されてるアクセスキーID
? secretAccessKey: # 成功画面に表示されてるシークレットアクセスキー
This would update/create the AWS Profile in your local machine
? Profile Name: default
Successfully set up the new user.
准备Nuxt应用程序。
使用”create-nuxt-app”来准备基础应用程序。在想要创建应用程序的目录中执行以下命令。各个选项根据个人喜好选择。
$ npx create-nuxt-app nuxt-amplify
create-nuxt-app v3.2.0
✨ Generating Nuxt.js project in nuxt-amplify
? Project name: nuxt-amplify
? Programming language: JavaScript
? Package manager: Npm
? UI framework: Vuetify.js
? Nuxt.js modules: Axios
? Linting tools: ESLint, Prettier
? Testing framework: Jest
? Rendering mode: Single Page App
? Deployment target: Static (Static/JAMStack hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
我们试试完成后启动并运行。
$ npm run dev
(省略)
i Waiting for file changes
i Memory usage: 415 MB (RSS: 516 MB)
i Listening on: http://localhost:3000/
请访问以下链接:http://localhost:3000/,若您能看到下方的屏幕,则表示一切良好。
顺便为后续工作使用generate命令生成文件。
$ npm run generate
只要创建了dist目录并放入内容,就可以了。
创建Amplify的后端
在Nuxt项目的根目录下,执行以下命令,进行配置:
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project nuxtamplify
? Enter a name for the environment dev
? 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: .
? Distribution Directory Path: dist
? Build Command: npm.cmd run-script generate
? Start Command: npm.cmd run-script start
这样一来,以下内容将会被更新。
/amplifyディレクトリが作成される。このディレクトリにはバックエンドの定義をコードベースで実装していき、Infrastructure as Codeを実現できる。
aws-exports.jsが作成されてバックエンドの情報が保存される。
.gitignoreが更新されていくつかのファイルが指定される。
AWS Console上にプロジェクトが作られる。 ???
安装适用于Amplify前端的库。
接下来,从Nuxt的前端中使用npm安装Amplify库。
$ npm install aws-amplify @aws-amplify/ui-vue
然后,在Nuxt的/plugins目录中创建amplify.js文件,并将安装的库作为插件加载。
import Vue from 'vue'
import Amplify from 'aws-amplify'
import '@aws-amplify/ui-vue'
import awsExports from '../aws-exports'
Amplify.configure(awsExports)
Vue.use(Amplify)
在nuxt.config.js文件的plugins数组中指定要加载的已创建插件。
// ...
plugins: [{ src: '~/plugins/amplify.js', ssr: false }],
// ...
只要在这种情况下运行 npm run dev 并且不出现构建失败,就应该没有问题。
创建和部署一个GraphQL API。
接下来,我们将创建一个API。在Amplify中,可以创建REST API和GraphQL API中的任何一种。这次我们尝试使用GraphQL。
$ amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: todoapi
? Choose the default authorization type for the API API key
? Enter a description for the API key: todo
? 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
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)
? Do you want to edit the schema now? No
以上的话,Graph QL的模式也会自动生成。我们来看一下文件的内容。
type Todo @model {
id: ID!
name: String!
description: String
}
已经创建了一个模型,可以存储id、name和description数据的模式。它被指定为@model,这是由GraphQL转换库提供的指令。有了它,表格和CRUD功能就准备好了。换句话说,API的实现基本上已经完成了。
所以,让我们部署GraphQL API吧。
$ amplify push
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | ----------------- |
| Api | todoapi | Create | awscloudformation |
? Are you sure you want to continue? Yes
? 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
让我们来确认一下,API是否已经创建成功。
$ amplify status
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | ----------------- |
| Api | todoapi | No Change | awscloudformation |
GraphQL endpoint: https://######################.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: ######################
然后让我们尝试从AWS控制台上进行确认。
$ amplify console
通过点击这个按钮,下面的页面会打开。如果什么都没有显示出来,可能是因为地区设置为了俄亥俄之类的地方,请在右上角的菜单中将地区切换成东京。
请点击这个链接选择后端,然后在下面的页面中选择在AppSync中查看。
连接前端和API
让我们在Nuxt前端应用程序中准备一个页面,以调用API。
<template>
<div>
<h1>TodoApp</h1>
<v-text-field v-model="name" label="Name"></v-text-field>
<v-text-field v-model="description" label="Description"></v-text-field>
<v-btn @click="createTodo">Create</v-btn>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.name }} : {{ todo.description }}
</li>
</ul>
</div>
</template>
<script>
import { API } from 'aws-amplify'
import { createTodo } from '~/src/graphql/mutations'
import { listTodos } from '~/src/graphql/queries'
export default {
data() {
return {
name: '',
description: '',
todos: [],
}
},
async created() {
await this.getTodos()
},
methods: {
async createTodo() {
const { name, description } = this
if (!name || !description) return false
const todo = { name, description }
await API.graphql({
query: createTodo,
variables: { input: todo },
})
this.name = ''
this.description = ''
this.getTodos()
},
async getTodos() {
const todos = await API.graphql({
query: listTodos,
})
this.todos = todos.data.listTodos.items
},
},
}
</script>
这段代码可以实现获取初始的待办事项和添加新的待办事项。但是,通过使用Amplify的GraphQL,可以借助subscription功能实现实时数据更新。这个功能在API创建时会自动生成,所以不需要特别设置,只需读取配置即可实现。由于是实时同步,所以不再需要位于createTodo末尾的this.getTodos()。
<template>
<div>
<h1>TodoApp</h1>
<v-text-field v-model="name" label="Name"></v-text-field>
<v-text-field v-model="description" label="Description"></v-text-field>
<v-btn @click="createTodo">Create</v-btn>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.name }} : {{ todo.description }}
</li>
</ul>
</div>
</template>
<script>
import { API } from 'aws-amplify'
import { createTodo } from '~/src/graphql/mutations'
import { listTodos } from '~/src/graphql/queries'
import { onCreateTodo } from '~/src/graphql/subscriptions'
export default {
data() {
return {
name: '',
description: '',
todos: [],
}
},
created() {
this.getTodos()
this.subscribe()
},
methods: {
async createTodo() {
const { name, description } = this
if (!name || !description) return false
const todo = { name, description }
await API.graphql({
query: createTodo,
variables: { input: todo },
})
this.name = ''
this.description = ''
},
async getTodos() {
const todos = await API.graphql({
query: listTodos,
})
this.todos = todos.data.listTodos.items
},
subscribe() {
API.graphql({ query: onCreateTodo }).subscribe({
next: (eventData) => {
const todo = eventData.value.data.onCreateTodo
if (this.todos.some((item) => item.name === todo.name)) return // remove duplications
this.todos = [...this.todos, todo]
},
})
},
},
}
</script>
添加认证功能
您可以在Amplify中添加身份验证。身份验证是通过AWS的Cognito实现的。
$ amplify add auth
Do you want to use the default authentication and security configuration? Default configuration
Warning: you will not be able to edit these selections. # 以下の設定は設定後の変更不可
How do you want users to be able to sign in? Email
Do you want to configure advanced settings? No, I am done.
直译为中文:
仅需这样准备就完成了。接下来需要将服务部署,必须进行推送。
本句提及了準備(准备)和デプロイ(部署)等IT相关词汇,可以使用更贴近技术语境的表达方式。以下为可选的多个表达方式:
1. 就这些就准备好了,之后只需要推送一下服务就行了。
2. 就这样准备完成了,现在只需要推送服务来部署。
3. 就这样准备工作就做好了,剩下的就是推送以进行服务的部署。
$ amplify push
? Are you sure you want to continue? Y
现在已经完成了Cognito的设置。接下来,让我们尝试插入由Amplify提供的Vue组件。
<template>
<amplify-authenticator>
<h1>TodoApp</h1>
<v-text-field v-model="name" label="Name"></v-text-field>
<v-text-field v-model="description" label="Description"></v-text-field>
<v-btn @click="createTodo">Create</v-btn>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.name }} : {{ todo.description }}
</li>
</ul>
<amplify-sign-out></amplify-sign-out>
</amplify-authenticator>
</template>
组件的子节点将在认证通过后显示。而组件只是用于显示所谓的退出登录按钮。根据文档,样式似乎是可以自定义的。下面是默认的外观,使用英文。
登录后,将显示子节点的内容。
这个认证可以只用这个就完成。当然,在Cognito这一边也可以进行账户管理。关于登陆,除了提供的组件之外,还可以利用库中提供的API进行自定义处理。例如,在注册账户信息时可以添加额外的信息来实现。
将应用程序部署到托管环境中。
使用Amplify的CLI进行部署后,可以在S3上进行托管。立即进行设置吧。
$ amplify add hosting
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Manual deployment
这样设置就可以了。现在让我们部署到托管环境上试试看吧。
$ amplify publish
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------------- | --------- | ----------------- |
| Hosting | amplifyhosting | Create | awscloudformation |
| Api | todoapi | No Change | awscloudformation |
| Auth | nuxtamplify2271a807 | No Change | awscloudformation |
? Are you sure you want to continue? Yes
...
✔ Deployment complete!
https://dev.XXXXXXXXXXX.amplifyapp.com
点击这个链接,我认为你就可以使用这个应用了。
下一步 (xià yí bù)
我认为只用几个小时就可以实现一个简单的应用程序。
虽然前面重复了一次,但通过Amplify,以下功能都可以轻松实现,所以文档主要以英语为主,我们可以一边查找资料一边逐步高效地开发应用程序!
-
- Authentication
-
- DataStore
-
- User File Storage
-
- Serverless APIs
-
- Analytics
-
- AI/ML
-
- Push Notification
-
- PubSub
- AR/VR
故障排除
在构建时被Linter狠狠批评
您可能在Prettier的配置中遇到了问题,您可以尝试更换.prettierrc文件来解决。
{
"tabWidth": 2,
"arrowParens": "always",
"trailingComma": "es5",
"printWidth": 80,
"semi": false,
"singleQuote": true,
"bracketSpacing": true,
"useTabs": false,
"endOfLine": "auto
}
如果您已经安装了VSCode的扩展程序Vetur,那么有可能Vetur的HTML默认格式化程序是prettyhtml。您可以通过工作区设置将格式化程序更改为prettier。