Web初心者がAWSを使ってサーバーレスwebアプリケーションを作成

## はじめに

現在修士1年でバイオインフォマティックス系の研究をしています．

卒論で開発した機械学習を用いた手法を論文化するためにwebアプリケーション化する必要があり，AWSを用いてサーバーレスwebアプリケーションを作成しました．

一ヶ月前まではhtmlすらほぼ触ったことがなく，javascriptやcssましてやAWSは使用したこともない完全なweb初心者でしたが，webアプリケーションを比較的簡単に実装コスト少なめで作成することができたのでその流れを紹介します．

web初心者だけどwebアプリを作成してみたい!といった方の参考になれば幸いです．(実装の詳細などは長くなるので全体的な流れだけ紹介します．)



### どんなアプリケーションを開発した？

今回開発したアプリケーションは以下のようなものです．

1. webページでユーザーからメールアドレスと予測対象のファイルを受け取る
2. 受け取ったファイルを前処理して予測
3. 予測結果をwebページでユーザーに表示

このうちAWSを用いたのは1と3の部分で，2の前処理と予測は処理が重いので研究室のサーバーを使って行うようにしました．

ざっくりと図にすると以下のような感じです．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/738376d8-1a8e-2e2a-fc87-c54c0a98f8af.png)


### なぜAWSを使用した？

今回AWSを用いて開発を行いましたが，研究室のwebサーバーを使って開発することも可能でした．

しかしあえてお金がかかるAWSを使ってwebツールを開発した理由には以下の点が挙げられます．
(AWS以外で開発をしたことがないのでほとんど受け売りです)

* めったにダウンしない
  たまに障害なども起きていますが，研究室のwebサーバーよりは圧倒的にダウンしにくいです．

* セキュリティ対策
  初心者が自分で対策するよりもAWSの方が安心です．

* 安い
  AWSは月々に使用した分だけ料金を払うという従量課金制のシステムなのでアクセス数が少ないサイトなら料金はかなり安いです．今回作成したアプリだと多めに見積もっても月300円程度です．データの転送に9割のお金がかかっているので，データの転送が少ないアプリならもっと安いと思います．

* たまたまAWSに詳しい人が身近にいた
  研究室にAWSに詳しい社会人ドクターの方がいてAWSを薦めてくださいました．
  （正直この点が一番大きいです．)

他にもログが残る，実装コストが少ないなどのメリットが挙げられます．



### AWSのデメリット

実際に開発してみて感じたAWSのデメリットは以下の2つです．

1. 公式ドキュメントが分かりにくい
   何かわからないことがあった時検索するとAWSの公式ドキュメントがたくさん出てきますが，正直わかりづらいです．特に最初の方は全然理解できませんでした．
   分かりやすい記事を挙げてくれている人がいるので初めのうちはそちらを参考にするのがいいと思います．

2. 料金を見積もるのが難しい
   従量課金制で安く抑えられるのは良いのですが，実際の料金がいくらになるのか概算するのはかなり難しいです．

3. 慣れが必要
   当たり前といえば当たり前ですが，多少の慣れが必要で慣れるまでは少し苦戦するかもしれません．
   しかし一度慣れたら素早く開発できるようになりました．





## 開発手順

ここからはどのように開発を進めていったかを書きます．

### 1. AWSアカウントの作成

まずは[公式サイト](https://portal.aws.amazon.com/billing/signup#/start)から自分のAWSアカウントを作成してみました．

アカウント作成の際クレジットカードの登録が必要になりますが，AWSは1年間の無料利用枠が設けられているのでその枠内であれば無料で使用できます．

住所を英語表記で入力する必要があり戸惑ったのですが，[こちら](https://aws.amazon.com/jp/register-flow/)の住所の書き方を参考に登録を行いました．

### 2. IAMユーザーの作成

1で作成したAWSアカウントはルートユーザーといって全ての権限を持っています．

ルートユーザーは権限が強すぎるので権限を制限した開発用のユーザーを作成することが推奨されています．

作成の際には以下の記事を参考にしました．

[[AWS] 管理者用のIAMユーザーを作成する](https://canon1ky.hatenablog.com/entry/2019/01/02/004323)

[AWSアカウントでのIAMユーザーの作成](https://qiita.com/kzykmyzw/items/ca0c3276dfebb401f7d8)

### 3. サーバーレスを理解

今回は研究室の先輩からの薦めでサーバーレス・アーキテクチャを使用してwebアプリケーションを作成しました．

サーバーレス・アーキテクチャとはその名の通りサーバーの管理がいらないアーキテクチャのことです．

最近流行っているようなので聞いたことある方も多いかもしれませんが，web初心者の私は聞いたことがなかったので，以下のサイトなどでまずサーバーレスとは何かから勉強しました．

[サーバーレスでプログラムを実行できる「AWS Lambda」とは](https://business.ntt-east.co.jp/content/cloudsolution/column-26.html)

[AWSを使ってサーバレスWebアプリケーションを10分程度で作る方法](https://tech.yayoi-kk.co.jp/entry/2018/12/12/103201)



サーバーレス・アーキテクチャを使用すれば，webサーバーを作成せずにユーザーがアクセスするエンドポイントとユーザーがアクセスしてきたときのパラメータなどに従って処理を行う関数を定義することで動的なwebページを表示することができます．

具体的には以下のようなイメージです．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/1e18c467-76ce-4f40-839a-4355345805b1.png)




[API Gateway](https://aws.amazon.com/jp/api-gateway/?hp=tile&so-exp=below)はエンドポイント(ユーザーがアクセスするURL)などの役割を果たしてくれるサービスで，[Lambda](https://aws.amazon.com/jp/lambda/?hp=tile&so-exp=below)はサーバー不要で定義しておいた処理を実行してくれるサービスです．

API Gatewayの詳しい説明は以下のサイトなどをご覧ください．
[5分でわかるAmazon API Gateway](https://recipe.kc-cloud.jp/archives/7944)



今回開発した上で感じたサーバーレスのメリットは以下の通りです．


1. サーバーサイドの知識がなくても開発可能
   サーバレスなのでサーバー側の知識がなくても開発することができます．
   今回はなるべく実装コスト少なめでアプリを開発することが目的だったので助かりました．

2. サーバーの運用が不要
   自分でサーバーを構築した場合，継続的なメンテナンスや何かエラーが起きた時の対処などをしなければいけませんがそういったことが不要になるので楽です．

3. 言語のサポートが豊富
   AWS Lambdaでは現在 Java、Go、PowerShell、Node.js、C#、Python、Rubyをネイティブサポートしています．

   普段使用しているPythonで開発することができ，新たに言語を勉強する必要がありませんでした．

他にも料金など様々なメリットがあり，以下のサイトに詳しくまとまっているので参考にしてください．

[なぜサーバーレスが注目されているのか？ゼロから学ぶサーバーレスアーキテクチャ（FaaS）入門](https://mmmcorp.co.jp/column/serverless/)



### 4. 簡易サーバーレスwebアプリを作成

次にサーバーレスの雰囲気を理解するために実際にサーバレスwebアプリを作成してみました．

この際以下のサイトの通りにサーバレスwebアプリを作成しました．

[API GatewayとLambdaで動的Webコンテンツのサーバレス化に挑戦してみた：その１](https://triobog.hateblo.jp/entry/2018/09/23/234739)

このサイトでは，URLの最後によく付いている`?id=20124`のようなURLパラメータに従って動的にwebページを表示するということをやっています．

このサイトの手順に則ればサーバーレスでユーザーの入力に基づいて動的に処理を行うwebページを作成する方法がなんとなく分かると思うので是非試してみて下さい．



実際に作成してみて最終的にサーバーレスwebアプリを作成するには

1. ユーザーに表示するwebページのhtmlの実装
2. ユーザーからの入力を受け取り処理を行う関数の実装

が必要ということが分かりました．



### 5. html, css, javascriptの勉強

まずhtmlの実装が必要ということが分かりましたがhtmlやcssなどのwebページを作る時の基本的な知識が全くなかったので初心者向けの本を一冊読んで基礎を勉強しました．

htmlやcssを勉強できる本やサイトはたくさんあるので，初心者の方は何でもいいので軽く勉強するのが良いと思います．



### 6. Bootstrapでwebページのhtmlを作成

webページのhtmlを作成する際には[Bootstrap](https://getbootstrap.com/)というwebアプリケーションフレームワークを用いて開発しました．

細かい説明は省略しますが，Bootstrapを使うと今どきのお洒落なwebページをCSSを書かずにhtmlだけで簡単に作成することができます．

例えば以下のようなwebサイトのトップによくあるナビゲーションバーを自分で作成するのは大変ですがBootstrapを用いればコピペで作成できます．

![スクリーンショット 2020-06-14 0.01.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/e9a2771e-c0d8-844e-42c4-f9b7d487081d.png)

自分がwebページに欲しいものをコピペで組み立てていくとそれっぽいものが作れるのでおすすめです．



また，Bootstrapをベースとして更に色々な機能が追加されている[MDBootstrap (Material Design for Bootstrap)](https://mdbootstrap.com/docs/jquery/components/demo/)もおすすめです．

Bootstrapにはフッターを作成する方法がないのですが，MDBootstrapなら以下のような良い感じのフッターが簡単に作れます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/664c3cd0-1aa9-ba95-8944-be783911c9b0.png)


他にもBootstrapにはない機能が色々追加されており，個人的にBootstrapよりも更にお洒落な感じでデザインセンスがない私のような人間でもそれっぽいものが作れたのでBootstrapよりもおすすめです．

こちらは有料版もありますが，無料版でも十分に高機能です．



実際には以下のようなユーザーからメールアドレスと予測対象のファイルを受け取るwebページを作成することができました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/77a77ff0-287a-196b-b17d-dcd1580e74b1.png)


これはBootstrapとMDBootstrapで提供されている要素を組み合わせただけなので比較的簡単に作成することができます．



### 7. 実際のAWSを用いたシステムの構築

webページのhtmlを作成することができたので，次にユーザーから送信されてくるファイルを処理するシステムの構築を行いました．

この記事の前半の方の[どんなアプリケーションを開発した？](#どんなアプリケーションを開発した？)で書きましたが，予測自体を AWSで行うとお金がそこそこかかるので研究室のサーバーで行う必要がありました．

そのためユーザーから受け取ったファイルやメールアドレスを研究室のサーバーに転送して予測を行い予測結果を再びAWSに送信する以下のようなシステムを構築しました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/2c6edb22-a5a3-52ec-e837-b26f38c97baa.png)


黄色で囲っているのがAWSのサービスです．



AWS側では
1. ユーザーから送られてきたファイルを一時的にAWSの[S3 (Simple Storage Service)](https://aws.amazon.com/jp/s3/?hp=tile&so-exp=below)というファイルを保存できるストレージサービスに保存しておく
2. メールアドレス，S3のファイルの保存場所，ジョブIDなどのジョブ情報をAWSの[SQS (Simple Queue Service)](https://aws.amazon.com/jp/sqs/?hp=tile&so-exp=below)というメッセージを貯めておくことができるメッセージキューに入れておく

研究室サーバー側では
1. SQSにジョブが入っているか定期的に確認
2. SQSにジョブが入っていたら取り出す
3. ジョブ情報をもとにS3から対象のファイルを取り出す
4. 予測を実行
5. 予測結果をS3にアップロード，予測結果を表示するURLをユーザーに送信

というようなことを行っています．



SQSを利用することにより研究室サーバー側でジョブのスケジューリングを行う必要がなくSQSに入っているジョブを１つづつ実行すれば良いので楽です．

ファイルをわざわざS3に送信しているのは，SQSの最大メッセージサイズが256KBでファイルが大きい場合受け取れないからです．(後から気付きましたが拡張クライアントライブラリというものを使用すれば2GBまで送信できるらしいです)

Lambdaや研究室のサーバーからSQSやS3をpythonで操作する際は[boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)というライブラリがあるのでそれを使用しました．

以下に実装の具体例があります．
[S3の操作実装例](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-examples.html),  [SQSの操作実装例](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/sqs-examples.html)





続いて結果を表示するシステムは以下のように作成しました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/bfb561ad-4ca5-a972-12df-04aec51c6e6d.png)


流れとしては以下のようになります．

1. URLパラメータとしてジョブIDがついている結果を表示するページのURLをユーザーに送信
2. ユーザーがアクセスしたらAPI GatewayがLambdaにパラメータを送信
3. Lambdaがパラメータをもとに対象の予測結果をS3から取り出してAPI Gatewayに返却
4. API GatewayがLambdaから受け取った予測結果をhtmlフォーマットに埋め込んでユーザーに返却



各ジョブ固有の結果を表示するためにジョブIDをURLパラメータとして受け取り，ジョブIDに基づいて予測結果を取り出すようにしました．



システムの全体像は以上です．

ユーザーからファイルを受け取って処理を行い，その処理結果をユーザーに返すサーバーレスwebアプリケーションを作成することができました．

詳しい実装方法などは別の記事で紹介したいと思います．



## まとめ

かなり長くなってしまいましたが以上のような流れでサーバーレスwebアプリケーションを作成しました．

ついこの前までweb系の知識が全くない初心者でしたが作成にかかったのは3週間程度でかなり時間的コスト低めでwebアプリを作成することができたのではないかと思います．

AWSを用いずに開発をしていた場合はサーバーサイドの勉強や実装，ジョブスケジューリングシステムの実装など他にも色々勉強や実装をする必要がありもっと時間がかかったと思います．

AWSの扱いは最初は難しいのですが，少し慣れると簡単にwebアプリを作成することができるようになるのでぜひ試してみて下さい．