【AWS Amplify ノウハウ】 1. バックエンドとフロントエンドは分離しましょう!

2020.07.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!コンサル部のテウです。

私はスタートアップ環境にも興味を持っており、スタートアップ等で迅速なサービス開発ができる AWS Amplify にも興味を持っています。なので、普段 AppSync や Amplify を用いてサイドプロジェクトをしたりしますが、今回は特に AWS Amplifyを実際に使ってみて感じたノウハウになれるようなことをまとめるブログシリーズを企画してみたいと思いました。

本シリーズでは Amplify の基礎部分には触れず、一度でも Amplify を使ってみた方々の役に立つそうな情報を要約してお伝えしますので、基礎部分につきましては公式文書のチュートリアル他のブログを参照してください :)

今日はまず、バックエンドとフロントエンドは分離しましょう! というタイトルでブログを書いてみます!

それでは始めます!:)

バックエンドプロジェクトを分離するってどういうこと??

AWS Amplify公式ドキュメントを読んでみると、自然にフロントエンドプロジェクトにバックエンドプロジェクトを入れる、下のような構成が頭の中に浮かぶでしょう。

...
amplify/
src/
node_modules/
package.json
...

サービスを最初から作る際、多くの場合、フロント側と通信するAPIサーバーを先に作ると思いますが、AWS Amplify を活用すると GraphQL Schema を作成するだけで CRUD などの機能を持った API サーバがすぐ利用できるようになり、とても魅力的で便利に使えると思います。それだけでなく、フロントと同じプロジェクトにバックエンドのリソースが定義されているため、プロジェクトを切り替えながら作業する必要もないので良いんじゃないかと思われるかもしれません。

なのに、いきなりバックエンドプロジェクトを分けるなんてどういうこと??って思う方もいらっしゃるのではないでしょうか。

ですよね。場合によっては、上の考えが正解かもしれません。ですが、普段サービス開発をすると、アプリやウェブの実装は必須であり、その後のコンテンツ管理や会員管理等のための管理者用のアドミンプロジェクトも一緒に作ることが一般的でしょう。こういった場合、「アプリ+アドミン」の組み合わせだったり、「ウェブ+アドミン」の組み合わせだったりするだけでも、開発のターゲットになるクライアント側のプラットフォームが2種類を超えてしまいます。

さらに、クライアント用のiOS/Android/ウェブのプラットフォームを開発し、管理者用でマスターアドミン/XXX用、アドミン/OOO用のアドミンを開発しないといけないのであれば、各プロジェクトを別々セッティングされますか?! 何か統合された一つのリポジトリをおいて、該当する(バックエンド)リポジトリでアップデートされたものだけをクライアントから pull して実装・管理したくないですか?

上記以外にも、そもそもフロントとバックエンドは観点は異なるがので、今後も問題になりそうなことはたくさんあるかと思います。その中でも、私が考えるバックエンドプロジェクトをフロントプロジェクトから分離することで得るメリットを紹介したいと思います。

バックエンドプロジェクトを分離することで得るメリット

1.バックエンドとフロントのSeparation of Concernを実現しやすい

AWS Amplify が提供してくれる機能らは素晴らしくて便利ですが、実際にサービス開発をしてみると Amplify が提供してくれる機能だけではすべてのケースが充当されることはそんなに頻繁にないと思います。こんな場合に、別途のバックエンドプロジェクトを分離しておけば、当プロジェクト内で custom-backend/ といったフォルダーをおいて、その下に関連しているコードを作成した方がコードの管理面で楽になるかと思います。そうすると、カスタム機能として AWS Lambda を活用した AppSync の Custom Resolver を開発したり、AppSync とは完全に分離して API Gateway + Lambda の構成などの AWSの様々なサービスを活用したアプローチなどの方法も適用できると思います。

なお、作成したカスタムコードのテストコードを作成したり、シードデータを入れたりするなどの作業をするにも、バックエンドプロジェクトが別途で分離されていた方が様々な観点でより直感的、かつ、管理しやすい形ではないかと思います。

2.複数のメンバーが一緒に作業しやすくなる

現在はサービス開発をお一人でされているとしても、継続してお一人で開発することを念頭に置いて開発される方は少ないと思います。結局、何かをちゃんと作るためには、お一人で開発するよりは、チームで開発する場合を念頭に置かないといけないですよね。こんな場合もバックエンドプロジェクトを分離することが当然直感的で管理しやすいと思います。

特に、バックエンドプロジェクトを Github等に push して、pushされる度に Slack等の協業用メッセンジャーにお知らせが来るように設定しておくと、他のチームメンバーがバックエンドプロジェクトで何かが更新されたことがすぐわかるようになり、それぞれが担当しているフロントプロジェクトで amplify pull しないといけないことが簡単にわかることができます。

3.将来的にバックエンドプロジェクトをマイグレーションするにももっと楽になる

私の個人的な見解としてAWS Amplifyは、初期のスタートアップサービスのMVPのためには、非常に大きい効率性とスピードを与える素晴らしいツールではないかと思っておりますが、ある程度サービスが安定し、機能が高度化されるにつれ、特定の時点で脱 Amplify化をしなければならないと思っております。その際、バックエンドプロジェクトが分離されていなければ、漸進的にマイグレーションをフロントエンドプロジェクト内に、バックエンド featureブランチを作り、作業をしなければならない、何かすっきりしない状況になる可能性が高いと思います。1番のメリットにて紹介しました関心の分離(Separation of Concern)にもある程度含まれる内容ですが、コードの形象管理という観点からみても、フロントプロジェクトにバックエンド関連の commitログを積むことは、後ほどcommitログのコンベンションを作ることにもよくないですし、ロールバックやバージョン管理も難しくなる可能性が高いでしょう。

それで、どうすれば良いの?

上記の理由に共感し、バックエンドプロジェクトを分離すると決めたならば、バックエンドを分離することは簡単です。これからよく使われる下のコマンドだけに慣れれば問題ないと思います。

  • amplify push
  • amplify pull
  • amplify codegen

Amplifyで定義されたリソースは AWS上にデプロイされて管理されるので、追加のプロジェクトを作ったとしても amplify pull だけ実行すれば、すぐ該当の Amplify プロジェクトに紐づきます。

まず、新しいプロジェクトを作ってみましょう。

$ mkdir amplify-backend
$ cd amplify-backend
$ amplify pull

amplify init をしなくても amplify pull だけ入力しても AWS profile と Amplifyプロジェクトが選択できます。

次は新しく作ったバックエンドプロジェクトから何かを修正して amplify push しておきます。そして、フロントエンドプロジェクト側で amplify pull & amplify codegen だけしていただければ、フロントエンドプロジェクトとバックエンドプロジェクトがよく分離されたのが分かります。 その後は、フロントエンドプロジェクトでは絶対にバックエンド設定部分は触らないこととし、バックエンドプロジェクトだけで作業するコンベンションを作っておけば、より直感的、かつ、効率の良いプロジェクト進行ができると思います。

フロントエンドプロジェクトの設定方法

バックエンドプロジェクトの設定が完了しましたら、フロントプロジェクトで amplify/ フォルダーを削除します。その後、また amplify pull をすると、バックエンドで設定した過程を同じく繰り返すこととなります。その時、amplify pull の最後の段階で、Do you plan on modifying this backend? と尋ねます。その際に、No を選択すれば、amplify/ フォルダーが生成されません。すなわち、バックエンドは別途管理するという宣言になります。

こうなると amplify codegen は動作しないです。プロジェクトルートで下のように schema.jsonをダウンロード(または最新化)します。

$ aws appsync get-introspection-schema --api-id ${APPSYNC_APP_ID} --format JSON schema.json

この schema.json ファイルがあれば amplify/フォルダーがなくても codegen が可能になります。下のように amplify codegen add を実行し、適切な選択をしてくれればセッティングは完了です!

$ amplify codegen add

最初のセッティングですので、 codegenの設定をしなければならないので add をつけましたが、後ほどバックエンドがアップデートされるたびに、下のコマンド2つで、フロントエンドプロジェクトにもバックエンドの変更された部分がすぐ反映されます。

$ aws appsync get-introspection-schema --api-id ${APPSYNC_APP_ID} --format JSON schema.json
$ amplify codegen

ノウハウの共有

上の方式通りにフロントエンドプロジェクトを設定することも良い方法ですが、実は私は amplify pull の最後の段階で Do you plan on modifying this backend? と聞かれたとき、Yes を選択する方をおすすめします。その理由は下記の2つですが、

  1. バックエンドの設定がそのまま見える環境でプロジェクトが構成されたとしても、フロントエンドプロジェクトでは amplify/ フォルダーを触らなないことにするコンベンションを決めておけば問題にならない点

  2. フロント開発者に amplify codegen で生成された複雑なコードではなく、 GraphQL schema そのものを共有したい場合、amplify/フォルダー 内部の backend/api/${API名}/schema.graphql を参照するようにできる点

特にschema.graphqlに各種フィールドに対する注釈及び説明等をつけておけば、schemaを作成した意図等がそのまま後にも確認できるようになり、フロント開発者とバックエンド開発者の間の協業がさらにスムーズになるような役割を果たしてくれます。

2020.07.30追記

なお、フロントエンド側のプロジェクトで amplify/ を .gitignore に設定しておくことで、よりセキュアーな開発が実現できると思います。

最後に

私は AWS Amplify に今年初めから改めて注目しています。AWS Amplify は迅速なサービス開発に必要な核心的な機能らをよく集めていると思いますが、その機能らをちゃんと活用できなければ、すく諦めて他のアプローチを探してみるケースが多いかと思います。しかし、私が直接 AWS Amplify を用いてサイドプロジェクトをやりながら感じたことは、思った以上多い機能をサポートしている点と、特に協業という観点でもスタートアップの環境で必要とする水準まではある程度サポートしてくれていると思います。

協業をよりスムーズにするためには関心を分離し、お互い独立な作業ができるような環境をセッティングすることが重要です。AWS Amplify を使うことにあたってもフロントエンドとバックエンドを分離して開発してみることはいかがでしょうか?

以上、コンサル部のテウでした。