用Amplify和GraphQL开发无服务器Web应用的团队开发经验记

首先,本文旨在

我之前有机会与少数人使用Amplify和GraphQL完全无服务器地开发Web应用程序。

我不知道是否对他人有所启发,但在那些即将消失的记忆完全消失之前,我想记录下我在技术和团队开发方面通过使用Amplify/GraphQL而得到的感悟,与熟悉的REST不同。

有许多特殊限制,最终变得稍微复杂,但为了简化,请将其视为一个简略版的待办事项应用程序,希望您能够阅读理解。

大致结构

undefined

首先,为什么选择Amplify呢?

在有很多选择的情况下,为什么当时决定使用Amplify呢?主要是因为有紧急交付和少人开发的限制,所以我们意识到以下几个方面:
※ 或许也有一种想先试用一下的心态。

    • 期待1: ユーザーに価値を届ける機能開発に時間を使いたい

認証, WebSocket, バックエンドAPI, データベース, … 等の機能開発をする上で必要なベースが比較的簡単に作れる。

期待2: スケーラビリティ、運用/保守のしやすさ

マネージドサービスをうまく利用することでユーザー数の増加や、運用/保守の手間を軽減できる。

期待3: 複数環境を簡単に作りたい

開発/テスト/商用環境といったように用途別の環境を簡単に作れる。

使用Amplify功能可以实现上述三个期望,所以我个人非常推荐!

我打算在接下来的内容中,主要写一些在开发过程中我所感受到的便利之处和困扰之事。

通过亲身实践的体验和经验总结的建议和心得。

你可以自动地成为全栈工程师。

在 schema.graphql 中进行以下描述,并执行 amplify push 将会创建 DynamoDB 表、解析器和 API。同时,还会创建用于调用 API 的标准查询,因此可以立即执行查询、变更和订阅。非常简单。

type Blog @model {
  id: ID!
  name: String!
  posts: [Post] @connection(name: "BlogPosts")
}
type Post @model {
  id: ID!
  title: String!
  blog: Blog @connection(name: "BlogPosts")
  comments: [Comment] @connection(name: "PostComments")
}
type Comment @model {
  id: ID!
  content: String
  post: Post @connection(name: "PostComments")
}

此外,由于提供了诸如@model,@connection,@auth,@function,@key等Directive,因此后端的基本配置也可以在这个Schema.graphql中完成。

只要记住,由于无法进行详细设置,因此您需要在CloudFormation一侧努力。

换句话说,编写这个模式与进行身份验证设置、数据库创建和API创建是相同的。
之后,只需进行前端开发,完全可以成为一个全栈工程师。

当您执行amplify add function时,只需将Lambda与DynamoDB Stream绑定即可完成以下设置。

? What event source do you want to associate with Lambda trigger? Amazon DynamoDB Stream
? Choose the graphql @model(s) Blog

前端和后端都可以使用TypeScript进行开发。

考虑到团队规模的限制,我们希望尽可能限定使用的语言/技术。
因此,这次我们统一选择了TypeScript作为前端和后端的开发语言。
与上述全栈工程师的讨论有关的是,任何人都可以在任何层面上进行接触,
按照用户故事逐步进行开发,这也是一个好处,因为团队成员的注意力自然而然地转向了用户价值!

此外,我认为在前端以及通过amplify add function添加的Lambda中,您可能还希望参考 src/API.ts 或 src/graphql/xxx.ts 等文件的类型。在这种情况下,您可以在 .graphqlconfig.yml 中进行以下修正,以便 Lambda 也可以使用这些类型。这样一来,您就可以利用生成的类型来进行 Lambda 的开发,并且享受到代码补全的好处,提高开发效率。

projects:
  xxx:
    schemaPath: src/graphql/schema.json
    includes:
      - src/graphql/**/*.ts
    excludes:
      - ./amplify/**
    extensions:
      amplify:
        codeGenTarget: typescript
        generatedFileName: src/API.ts
        docsFilePath: src/graphql
  yyy(←関数名):
    schemaPath: src/graphql/schema.json
    includes:
      - src/graphql/**/*.ts
    excludes:
      - ./amplify/**
    extensions:
      amplify:
        codeGenTarget: typescript
        generatedFileName: amplify/backend/function/yyy/ts/API.ts # 任意のパスを設定してください
        docsFilePath: amplify/backend/function/yyy/ts/graphql # 任意のパスを設定してください

可以在Multiple Environment中为每个开发者创建专用环境。

Amplify提供了一个名为Multiple Environment的功能,用于管理多个环境。
正如官方文档中所述,你可以为开发、测试和生产环境创建不同的环境。

スクリーンショット 2020-09-25 19.47.25.png

在Dev环境中,每个工程师都可以为自己准备并使用独立的环境,例如Dev1、Dev2等,因此可以轻松地尝试各种实验,即使环境崩溃也不会影响其他工程师,因此可以自由开发。
而且,只需执行”amplify env checkout 环境名”,即可轻松切换环境。

在CI / CD过程中使用Amplify无头模式!

由于Amplify的命令行执行是交互式的,因此在CI/CD中自动执行时会遇到困难。
在这种情况下,您可以使用Amplify Headless模式。

--yes flag

The --yes flag, or its alias -y, suppresses command line prompts if defaults are available, and uses the defaults in command execution.

按照文档中的说明,通过添加”–yes”选项,您可以在所有默认情况下进行。但是,在使用”–yes”选项时需要注意的是,这将强制执行后端的更改处理。例如,即使执行amplify pull –yes命令,也将强制执行CloudFormation堆栈的更改处理。在这种情况下,您可以通过以下方式执行,并将交互式询问的内容传递给命令。

AMPLIFY="{\
\"projectName\":\"app\",\
\"envName\":\"環境名\",\
\"appId\":\"アプリケーションID\",\
\"defaultEditor\":\"code\"\
}"

AWSCLOUDFORMATIONCONFIG="{\
\"configLevel\":\"project\",\
\"useProfile\":true,\
\"profileName\":\"default\"\
}"

PROVIDERS="{\
\"awscloudformation\":$AWSCLOUDFORMATIONCONFIG\
}"

FRONTENDCONFIG="{\
\"SourceDir\":\"src\",\
\"DistributionDir\":\"dist\",\
\"BuildCommand\":\"yarn generate\",\
\"StartCommand\":\"yarn start\"\
}"

FRONTEND="{\
\"frontend\":\"javascript\",\
\"framework\":\"vue\",\
\"config\":$FRONTENDCONFIG\
}"

amplify pull \
    --amplify $AMPLIFY \
    --frontend "$FRONTEND" \
    --providers $PROVIDERS

尽管使用了这个设置,但无法将对话设置为0(截至2020年9月),所以我使用了expect命令来解决这个问题。最终,我成功地在CodeBuild中实现了对多个AWS账户的CI/CD操作。

最終,CloudFormation

用Amplify之前,我們提到使用它可以輕鬆地且方便地設定幾個命令行,不再需要費力地編寫代碼。但對於曾經使用過的人來說,他們知道這實際上是在背後生成了CloudFormation模板。

因此,如果不能通过对话式命令行进行设置或者无法在schema.graphql中完全表示的部分,您将需要编辑CloudFormation模板来进行详细配置。我将举一个例子。

我想将Lambda放入VPC中。

比如,通过编辑team-provider-info.json和CloudFormation模板,可以实现如下的目标。

"Env名": {
  ...
  "categories": {
      "function": {
          "関数名": {
              "vpcSecurityGroupIds": [
                  "セキュリティグループID"
              ],
              "vpcSubnetIds": [
                  "サブネットID",
                  "サブネットID"
              ]
          },
      },
      ...
  }
}

"LambdaFunction": {
  ...
  "Properties": {
    ...
    "VpcConfig": {
      "SecurityGroupIds": {
        "Ref": "vpcSecurityGroupIds"
      },
      "SubnetIds": {
        "Ref": "vpcSubnetIds"
      }
    },
  ...
},

如果您想要设置其他DynamoDB表的备份,只需通过设置“DynamoDBEnablePointInTimeRecovery”: “true”来实现。基本上,您可以通过相同的策略来完成大部分配置。

試著參與團隊開發

我想使用Amplify来减少在后端开发上花费的时间,这样我可以将更多时间用于开发能够给用户带来价值的功能。使用Amplify后,构建后端的时间减少了,这降低了我一个人开发一个用户故事(功能)的难度。这样一来,前端工程师和后端工程师之间的沟通成本也减少了,虽然无法进行比较,但我认为这可能会提高开发速度。

另外,由于采用了托管服务和无服务器架构,运维工作和发布后的任务都减少了,这使我能够更集中地进行功能开发。

但是,由于前端和后端代码的紧密耦合,如果项目变得庞大或者人数增加,可能需要采取不同的方法,这是我感觉到的。

结束

    • 基本的にはAmplifyの良いところベースで書いてきました。ただ、フレームワークというのは使い始めは、細かいところでつまづくことも多いと思います。ただ、もし興味があるのなら、軽めの開発で試してみるのが良いのではと思います。

 

    GraphQLについても書きたいことがあったのですが、疲れた長くなってきたので、また次回にしようと思います。

可以考虑的文章

    • https://docs.amplify.aws/cli/graphql-transformer/directives

 

    https://docs.amplify.aws/cli/usage/headless
bannerAds