使用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控制台会在浏览器中打开,并要求添加用户。基本上,全部都可以使用默认设置。

image.png

我会继续前进到下一个画面。

image.png

我会保持现状并继续前进。

image.png

最后将显示以下画面,请不要关闭此页面。

image.png

我会返回控制台界面。

当你返回后,请根据显示在成功画面上的值输入密钥。请注意管理密钥以防泄露。配置文件名称可以是任意的,本次默认设置为”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/,若您能看到下方的屏幕,则表示一切良好。

image.png

顺便为后续工作使用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

通过点击这个按钮,下面的页面会打开。如果什么都没有显示出来,可能是因为地区设置为了俄亥俄之类的地方,请在右上角的菜单中将地区切换成东京。

image.png

请点击这个链接选择后端,然后在下面的页面中选择在AppSync中查看。

image.png

连接前端和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>

组件的子节点将在认证通过后显示。而组件只是用于显示所谓的退出登录按钮。根据文档,样式似乎是可以自定义的。下面是默认的外观,使用英文。

image.png

登录后,将显示子节点的内容。

image.png

这个认证可以只用这个就完成。当然,在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。

image.png
广告
将在 10 秒后关闭
bannerAds