【完全SPA】Sier出身者がWeb系企業へ転職するために作成したアプリの開発記録(Rails/Vue.js/AWS/Docker/CircleCI)

## 記事の内容

**Webアプリケーション開発の経験が少ないSE**が、Web系エンジニアになるべく作成したポートフォリオに関して、以下の情報をまとめます。

- ポートフォリオの紹介
- 技術選定理由
- おすすめの書籍やWeb媒体の紹介

同じような境遇の方の参考になればと思い、記事を書かせていただきました。

## 自己紹介

ももんがザムライ([@momonga11_d](https://twitter.com/momonga11_d))と申します。
文系学部で大学卒業後、中小規模のSierに就職し、7年間勤めました。
主にクライアント・サーバーアプリの設計、開発、パッケージソフトの顧客への導入に従事。使用言語は`VB.NET`でした。
よりモダンな環境で手を動かすエンジニアとしての技術を身につけたい思いで、Web系エンジニアへのキャリアチェンジを決意しました。

## ポートフォリオ「NOTENEXT」 紹介

### 概要

NOTENEXTは、**ノートとタスクを一緒に管理する**ためのアプリケーションです。
こういった課題を解決できます。

- チームの打ち合わせ中、議論をしていると新しいタスクが出てきた。議事録にメモしておこう
- 勉強用のノートを作成していると、新しく不明点が見つかった。あとで確認しよう
- NOTENEXTでは、作成したノートにタスクを設定することができます。

ノートとタスクを紐付けておくことで、**「あとでやること」が強調され**、埋もれないようになります。

### デモ

見ていただいた方が早いと思いますので、デモ用のgifファイルを貼っておきます。
なんとなくイメージしていただけますと幸いです。

![notenext_demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567216/990608d8-7ff2-dad5-e88b-56918ebf3006.gif)

### URL

https://notenext-app.com

<del>（※予告なく停止することがあります。また料金節約のため現在は低スペック環境で起動しております。ご了承ください）</del>
**※現在停止しております。**

### 作成背景

**タスクがメモの中に埋もれてしまう**、という課題を解決するために作成しました。

例えば、朝会などの打ち合わせ中にこれまで想定していなかったタスクが発生する、ということはよくあると思います。
前職では朝会の記録をテキストファイルに書く傾向にありました。日付がファイル名のテキストファイルが毎日増えていく、とイメージしてもらえるとわかりやすいと思います。
テキストファイルにタスクが記入されるわけですが、**そのようなタスク管理では一覧として確認することができません。**現在どのようなタスクがあり、いつまでに実施するのか、テキストファイルを開き、探さないとわからない状態でした。
(なお、ここでいうタスクはプログラム改修などのIssueに限ったものではございません)

#### 重要な補足

上記のような背景をもとに、既存のタスク管理アプリをたくさん調査しました。すると、**同じようなことを実現できるアプリを発見しました。**[stock](https://www.stock-app.info/) というタスク管理アプリです。
方針を変えるか悩みましたが、今回はポートフォリオ用のアプリということで、そのまま私の作りたいアプリを作成することとしました。
それどころか、UI面では非常に多くの部分を参考にさせていただいております。

**私のアプリは継続運用しない可能性が高い**ので、もし興味を持っていただいた方がおりましたら、是非[stock](https://www.stock-app.info/)を調べてみてください(stockさんの回し者っぽいですが、違います笑)。　


### 作成期間

2020年9月〜2021年5月頭
**大体８ヶ月**ぐらいです。予定より遅れてしまいました。
ほとんどの期間、働きながら作っていましたので、業務多忙時期はキツかったですね...。

### 詳細について

より詳細な情報はGithubの方をご参照ください。

https://github.com/momonga11/notenext-client

https://github.com/momonga11/notenext-server


## 技術概要

### 主要技術まとめ

- フロントエンド
  - Vue.js 2.6.11
  - Vuetify
  - axios(バックエンドとの非同期通信)
  - jest(自動テスト)
  - eslint/prettier(静的解析、フォーマッター)
- バックエンド
  - Ruby 2.7.3
  - Rails 6.1.3
  - RSpec(自動テスト)
  - Rubocop(静的解析、フォーマッター)
  - nginx(Webサーバー)
  - puma(APサーバー)
  - MySQL 8.0(データベース)
- インフラ
  - AWS(Amplify, Route53, CloudFront, S3, ACM, VPC, ALB, ECS, Fargate, ECR, RDS, SSM, CloudWatch)
  - Docker/docker-compose
  - CircleCI(バックエンドのCI/CD)
  - SendGrid(メール送信)

### インフラ構成図

![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567216/7b0dd94a-5f5d-2869-8c0c-d07db261d31b.png)

## 技術選定理由とおすすめ学習法

上記にまとめた技術に関して、**それぞれの選定理由と私が実施した学習方法**について、説明します。
なお学習方法に関しては書籍が多いです。理由としては、書籍は体系的な知識を得る方法としては非常に優れていると考えており、また私はSEとしてのキャリアが長いため技術本を読み慣れているためです。
完全にIT未経験の方の場合、**最初に書籍から入ると挫折しやすい傾向がある、** と言われます。そのため、例えば [Progate](https://prog-8.com/)や[ドットインストール](https://dotinstall.com/)などのWebの学習サイトから入り、プログラミングってどんなものなのか、を最初に知ることをお勧めします。

***

### アプリケーション全般

#### Webアプリ基礎

そもそも **Webアプリケーションである必要があるかどうか、** を最初に検討しました。
結論として、以下の理由よりWebアプリケーションが適していると判断しました。

- プロジェクトの参加者複数人が記入するため、インターネット下であれば場所を問わず利用できるアプリが良い
- スマートフォンでの利用もありだが、記録部分はPCで書く機会が多いため、優先度としてWeb > ネイティブ となる

##### その他の選択肢

`ネイティブアプリ, PWA, クライアント・サーバーアプリケーション`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352/ref=asc_df_4774142352/?tag=jpgo-22&linkCode=df0&hvadid=295686767484&hvpos=&hvnetw=g&hvrand=1513249748123730274&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009252&hvtargid=pla-524383766550&psc=1&th=1&psc=1)  | 書籍  |   |
| [ちゃんと使える力を身につける　Webとプログラミングのきほんのきほん](https://www.amazon.co.jp/%E3%81%A1%E3%82%83%E3%82%93%E3%81%A8%E4%BD%BF%E3%81%88%E3%82%8B%E5%8A%9B%E3%82%92%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%91%E3%82%8B-Web%E3%81%A8%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E5%A4%A7%E6%BE%A4-%E6%96%87%E5%AD%9D-ebook/dp/B00Z9IQ9C6)  | 書籍  |↑だけでも十分かも  |


### Webアプリの通信方式

今回はSPA（シングルページアプリケーション）の構成にしました。
メリット、デメリットは当然あるのですが、以下のような理由でSPAを選択しました。

- ユーザーがアプリに滞在する時間が長い
- また小規模のため初回起動時の遅さはあまり気にならない(はず)
- SEOを意識する必要がなかった
- SSRよりは学習コストが低い

##### その他の選択肢

`MPA, SSR, SSG`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [SPA・SSR・SSGについて整理してみた](https://kanat-blog.com/render-difference/)  | 記事 | わかりやすくまとまっている  |
| [シングルページアプリケーション（SPA）の導入メリット＆デメリット](https://www.oro.com/ja/technology/001/)  | 記事 | |

***

### フロントエンド

#### 言語

`HTML`, `CSS`, `JavaScript` のシンプル構成を採用しました。
CSSに関しては一部　`SCSS`を使っていますが、あまり恩恵はありませんでした（後述するCSSフレームワークにより、あまりCSSを書いていないため）。

重要なところは、`TypeScript`を採用していない点だと思います。
この点に関しては、技術的なメリデメで判断したわけではなく、単純に学習コストの問題が理由でした。
JavaScriptの基礎を学んだところでしたので、そこからさらにTypeScriptになると、開発着手時期が遅れてしまうため、JavaScriptで行くことにしました。余力のある方はTypeScriptを採用した方がいいと思います。

##### その他の選択肢

`SASS, TypeScript`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [1冊ですべて身につくHTML & CSSとWebデザイン入門講座](https://www.amazon.co.jp/1%E5%86%8A%E3%81%A7%E3%81%99%E3%81%B9%E3%81%A6%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8FHTML-CSS%E3%81%A8Web%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E5%85%A5%E9%96%80%E8%AC%9B%E5%BA%A7-Mana/dp/4797398892)  | 書籍 | 新し目のHTML、CSSの記法がわかります  |
| [HTML5/CSS3モダンコーディング フロントエンドエンジニアが教える3つの本格レイアウト](https://www.amazon.co.jp/HTML5-CSS3%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0-%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B3%E3%81%A4%E3%81%AE%E6%9C%AC%E6%A0%BC%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88-%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%80%E3%83%BC%E3%83%89%E3%83%BB%E3%82%B0%E3%83%AA%E3%83%83%E3%83%89%E3%83%BB%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9-%E5%90%89%E7%94%B0%E7%9C%9F%E9%BA%BB-ebook/dp/B0176GNY26)  | 書籍 | ちょっと古いですが、HTMLとCSSの書き方を体系的に学べます |
| [JavaScript本格入門 ～モダンスタイルによる基礎から現場での応用まで](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%EF%BD%9E%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B-ebook/dp/B01LYO6C1N/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=UVDJG50B5Z3N&dchild=1&keywords=javascript%E6%9C%AC%E6%A0%BC&qid=1624356108&s=digital-text&sprefix=javasc%2Cdigital-text%2C274&sr=1-1)  | 書籍 | 開発中、何度も読み返した良本です |

#### JavaScriptフレームワーク

SPAで構築するため、`Vue.js`を採用しました。
JSフレームワークの御三家と言われる(?)、`React`, `Vue.js`, `Angular`が候補となりました。
`Angular`はこの中だと大規模アプリ向けのため、最初に除外しました。
`React`と`Vue.js`を比較した結果、`Vue.js`の方が学習コスト低いと判断したため、採用することになりました。

`React`も`Vue.js`もコンポーネントという単位で部品を定義しますが、`React`の`JSX`はJavaScriptのコードの中にHTMLのタグが埋め込まれている形のため、HTML初心者には少し難しいと感じました。
一方、`Vue.js`はHTML、CSS、JSの記述場所がそれぞれ分かれており、フロントエンド初心者やデザイナーさんも読めるような構成になっていると感じました。この辺りは好き嫌いもあると思います。

なお、学習時及び開発開始時の`Vue.js`のバージョンは2系でしたので、3系ではございません。

##### その他の選択肢

`React, Angular`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [JavaScript: フレームワーク React/Vue/Angularについて](https://qiita.com/gumiTECH/items/13eb7da8224bf93c67b5)  | 記事 | ３大フレームワークを比較した良記事です |
| [超Vue.js 2 完全パック (Vue Router, Vuex含む)](https://www.udemy.com/course/vue-js-complete-guide/)  | 動画 | Vue.jsを学ぶならこれと公式だけで良いぐらいです。ただ2系の説明のため、3系の学習なら別のものがいいかも |

#### CSSフレームワーク

`Vuetify`を採用しました。
`Vue.js`との親和性が非常に高いのが理由です。車輪の再発明を多くの部分で抑制することができました。
また公式サイトが日本語に対応されていたのも理由の一つです。

##### その他の選択肢

`Bootstrap ※他にもたくさんありますが`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [Vuetify公式ドキュメント](https://vuetifyjs.com/ja/getting-started/installation/)  | Web | 公式が一番でした |


#### API通信

`REST`を採用し、JSONフォーマットでフロントエンド-バックエンド間の通信を実施しました。
`GraphQL`も検討しましたが、個人的にはRESTはHTTP通信を理解できるので、初学者は必ず抑えておくべき技術要素だと思っているため、APIを最初に作るならRESTが良いと思います。
またデータのフォーマットにはXMLも考えられますが(前職ではXMLだった)、記述量が多くなりサイズが増えがちなので、今はあまり使われないそうです。

##### その他の選択肢

`GraphQL`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [Webを支える技術 -HTTP、URI、HTML、そしてREST](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042)  | 書籍 | 初学者は読みにくいかもしれませんが、RESTやHTTPを学ぶにはとても良い書籍です |
| [axios](https://github.com/axios/axios)  | Web | フロントエンドでHTTP通信を実施するために利用したライブラリです |

***

### バックエンド

#### 言語

`Ruby`を採用しました。
この理由に関してはかなり個人的なものです。打算的なものも含みます。

- 動的型付言語の経験がなかったため、`Ruby, PHP, Python`のいずれかを使ってみたかった
- `PHP`は求人数は多いが古くから稼働しているシステムも多く、新しく学ぶ言語としては優先度は低かった
- `Python`は機械学習をやるのではあれば有りだが、そうでない場合は優先度は低いと判断した（日本での求人数も考慮）
- `Ruby`は日本発の言語であり、日本語のコミュニティが豊富。かつスタートアップ企業で多く採用されており、求人数も多い

もし静的型付言語で実装する場合は、今だと`Go`や`Kotlin`を選ぶと思います。特に`Go`は最近のスタートアップ企業では多く採用されている印象でした。

##### その他の選択肢

`PHP, Python, Go, Kotlin`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774193976)  | 書籍 | 筆者がQiitaで出版後に出たRubyのバージョンの差異を補足されていますので、要チェック |

#### フレームワーク

`Ruby on Rails`を採用しました。
`Ruby`といえばこれ、のようなイメージがあります。`Ruby`を使っている企業のほとんどが`Rails`を使っている気がするので、やっておいて損はないと思います。
速く、比較的簡単に実装できるため、中小規模のアプリを短期間で作成することを目指すのであれば最適だと思います。

##### その他の選択肢

`Sinatra, Hanami`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4-ebook/dp/B07JHQ9B5T)  | 書籍 | 自分はこの書籍で勉強しましたが、記載の通りバージョン6系ではありません。最新バージョンを学習する場合、やはりRailsチュートリアルをやるのが良いではと思います。 | 

#### データベース

`MySQL`を採用しました。
まずRDBMSかNoSQLかという観点がありますが、テーブルとして構造化されたDBの方が開発、運用のしやすさにメリットがあると思い、RDBMSを選びました。
NoSQLはよりパフォーマンスが求められる部分に導入するのが良いと思います。
その中で、`MySQL`を選んだ理由ですが、大きく以下のようなものがあります。

- シンプルかつ必要十分な機能を備えたRDBMS。作成するアプリに必要な機能は全て満たしている
- 前職で利用実績のある技術のため使い慣れていた
- 対抗馬として`PostgreSQL`が挙げられたが、こちらは分析系の機能が豊富だが、今回のポートフォリオでは不要だった

##### その他の選択肢

`PostgreSQL, SQLite`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ](https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6DB%E8%A8%AD%E8%A8%88-%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798124702)  | 書籍 | 初学者の場合は、同じ著者の『SQL徹底指南書』の方が良いかもしれません。 | 

#### Webサーバー

`nginx`を採用しました。
`Apache`との一騎打ちでしたが、大量アクセスの処理において、`nginx`に軍配が上がるため、選択しました。
例えば計算処理に時間がかかるAPI処理などがあれば、`Apache`を検討した可能性もあります。

##### その他の選択肢

`Apache`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [ApacheとNginxについて比較](https://qiita.com/kamihork/items/49e2a363da7d840a4149)  | 記事 | 比較することによって両者の機能がよくわかります |
| [nginxについてまとめ(設定編)](https://qiita.com/morrr/items/7c97f0d2e46f7a8ec967)  | 記事 | 設定ファイル作成に大変役立ちました |

#### APサーバー

`Puma`を採用しました。
`Rails5.2`から`Unicorn`ではなく`Puma`が標準のAPサーバーになったみたいですね。
`Puma`はマルチスレッドに対応しているので、スレッドセーフに作っていれば高速化が期待できます。
今回のアプリでは、あえて`Unicorn`に変える必要もないと思い、`Puma`のままとしました。

##### その他の選択肢

`Unicorn`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [Unicorn vs Puma vs Passengerの比較まとめ](https://scoutapm.com/blog/which-ruby-app-server-is-right-for-you-ja)  | 記事 |  |
| [PumaとUnicornの違い](https://blog.kasei-san.com/entry/2020/08/26/103831)  | 記事 |  |

#### 認証系

ブラウザの`localStorage`を利用したトークン認証を採用しました(devise_token_auth)。

ここは正直かなり悩みました。
`localStorage`には、セキュリティ上の問題が指摘されています。
https://techracho.bpsinc.jp/hachi8833/2019_10_09/80851
しかしながら、`localStorage`を利用しているアプリケーションは多々あり、一概に否定されているわけではありません。
比較対象として`Cookie`にトークンを保存する手法がよく挙がります。こちらはXSSの脅威には強いですが、HTTP通信において自動送信されてしまうため、CSRFの対策をしっかり行う必要があります。

また`JWT`をセッション管理に使おうという案も考えましたが、これは調査の結果、没にしました。
APサーバーがステートレスになるので、スケールしやすくなって良いじゃん、なんて思っていましたが、`JWT`単体ではログアウトや非常時にアカウント停止が即座にできない、というような問題があります。
https://qiita.com/hakaicode/items/1d504a728156cf54b3f8
`JWT`は本来`OAuth認証`で使われるべきで、認証・認可サーバーを別途用意することでAPサーバーをステートレスにできる、ということだと判断しました。
そのため、Firebase AuthenticationやAuth0などのIDasSのサービスを使う、という手もあるなと考えました。

ですが結局、`devise_token_auth`というgem（Rubyのライブラリ）を使って、トークン認証を実装することに決めました。
理由は、開発期間の問題とポートフォリオとしてどこまでの機能を盛り込むか、といったところになります。
`devise_token_auth`を使えば、メール認証によるサインアップやパスワードリセット、パスワード連続入力失敗によるアカウントロックなどの機能が標準で実現できます。今回は実施しなかったですが、OAuth認証もサポートされています。
またIDaaSを使った場合は、テスト環境の構築が容易ではなくなると思っています。もちろん商用レベルのセキュリティを担保するには検討した方が良いですが。

しかしこの結論が正解だとはあまり思えないので、認証周りはまだまだ勉強不足だと痛感しました。

##### その他の選択肢

`session, Cookie(sesson or token）, IDaaS, OAuth, JWT`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [devise_token_authの公式ドキュメント](https://devise-token-auth.gitbook.io/devise-token-auth/)  | web | 困ったら公式 |
| [【翻訳】devise-auth-token公式ドキュメント](https://sainu.hatenablog.jp/entry/2018/08/11/194319)  | 記事 | 上記のドキュメントを日本語訳してくれている記事 |
| [[Rails] devise token auth を使う](https://qiita.com/Masahiro_T/items/6bc49a625b437a7c2f45)  | 記事 | 実際にRailsで使う際の方法 |
| [OAuth&OIDC入門編](https://www.authlete.com/ja/resources/videos/20200317/)  | 動画 | OAuthやOpenID Connectについてわかりやすく解説されている |
| [世界一わかりみの深いOAuth入門](https://speakerdeck.com/noriyukitakei/wakarimioauth)  | スライド | 本当にわかりやすいOAuthの入門記事 |

### インフラ

あらためて、こちらがインフラ構成図となります。
以降、適宜参照していただくと、わかりやすいと思います。

https://github.com/momonga11/notenext-docs/blob/main/%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9/%E6%A7%8B%E6%88%90%E5%9B%B3.png

#### 全体として

`AWS`を全体的に採用しています。
世界で最も多く利用されているクラウドサービスです。`GCP`や`Microsoft Azure`がその他の選択肢となると思いますが、以下の理由で対象から除外しました。

- `GCP`はBigQueryなどの分析系の機能が充実しているが、今回のポートフォリオには不要
- `Microsoft Azure`はMicrosoft系の技術との親和性が高いが、今回はMicrosoft系の技術を採用していないため、メリットが大きくない

##### その他の選択肢

`GCP, Microsoft Azure, Oracle Cloud`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [Amazon Web Services 基礎からのネットワーク＆サーバー構築](https://www.amazon.co.jp/Amazon-Web-Services-%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%EF%BC%86%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E7%AF%89-%E6%94%B9%E8%A8%823%E7%89%88-%E5%A4%A7%E6%BE%A4-ebook/dp/B084QQ7TCF)  | 書籍 | AWSを最初に学ぶならこれがおすすめ。AWSに限らず、インフラ知識も少し学べる |
| [ゼロからわかる Amazon Web Services超入門](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%82%8B-Amazon-Services%E8%B6%85%E5%85%A5%E9%96%80-%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89-%E3%81%8B%E3%82%93%E3%81%9F%E3%82%93IT%E5%9F%BA%E7%A4%8E%E8%AC%9B%E5%BA%A7-ebook/dp/B07TFTGHMX/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=amazon+web+services+%E8%B6%85%E5%85%A5%E9%96%80&qid=1624433064&s=digital-text&sr=1-1)  | 書籍 | Route53やCloudFront+S3,ロードバランサーなどの解説があるのが上記との違い |

#### ホスティング

`AWS`のサービスである`Amplify`を採用しました。
最初は`S3`+`CloudFront`を検討していたのですが、`Amplify`は内部的に`S3`+`CloudFront`を一括で構築し、またCI/CDも併せて導入しやすいというメリットがありました。ちなみに、`Amplify`の機能は豊富なのですが、今回はホスティングサービスのみ活用しています。

##### その他の選択肢

`S3+CloudFront, Netlify, Vercel`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [フロントエンドエンジニアに捧げるAWS Amplify Console](https://dev.classmethod.jp/articles/aws-amplify-console-guide-lines-for-frontend-engineer/)  | 記事 |  |
※他にも多くの記事を参考にさせていただきましたが、今回は割愛させていただきます。

#### サーバーサイド(実行環境)

`AWS`のサービスである`ECS(Fargate)`を採用しました。
`EC2`でバックエンドを構築する手もありましたが、コンテナサービス(`ECS`)で構築すればOS側の考慮が不要のため、最適だと判断しました。
なお`ECS`には、`EC2タイプ`と`Fargateタイプ`があります。コンテナを起動する環境の違いですが、`EC2タイプ`の場合、OSやDocker Engineなどの管理をしなければなりません。
純粋にコンテナだけを管理するのであれば`Fagateタイプ`が良いですが、以前は**コンテナにSSH接続できない**という問題がありました。障害調査の場合などは、同様のコンテナ環境を`EC2タイプ`に一時的に構築し、SSH接続して確認しなければならなかったようです。
ですが、`ECS Exec`という機能がバージョンアップにより追加され、セキュアな通信で`Fargateタイプ`のコンテナに接続できるようになりました。
https://aws.amazon.com/jp/blogs/news/new-using-amazon-ecs-exec-access-your-containers-fargate-ec2/
これにより、慣れていない方でも`Fargate`を選択するメリットが大きくなったと思います。

##### その他の選択肢

`EC2`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [基礎から応用までじっくり学ぶECS Fargateを利用したコンテナ環境構築 #Fargate](https://dev.classmethod.jp/articles/developers-io-2020-connect-kaji-ecs-fargate/)  | 記事 | クラスメソッドさんのAWS記事は本当に参考になります |
※他にも多くの記事を参考にさせていただきましたが、今回は割愛させていただきます。


#### その他

ここからは`AWS`で利用したサービスを一部ピックアップしてご紹介します。

#### CloudFront+S3

画像ファイルの保管先として`S3`を採用し、またCDNとして利用したかったので、`CloudFront`を前に配置しております。
画像ファイルは、`Rails`の`ActiveStorage`を使って配信・保存しており、**CloudFront → Rails → S3** の順で配置することで、一度取得した画像ファイルなら、Railsを経由せず、CloudFrontからCDN経由で取得できるようにしました。

#### ECR

`ECS(Fargate)`で利用するコンテナイメージのリポジトリして、`ECR`を利用しました。
後述する`CircleCI`では、`ECR`にコンテナイメージをアップロードしたのち、`ECS`にデプロイする仕組みでCD環境を作成しました。

#### Systems Manager

色々なことができるサービスですが、私はシークレットなパラメータを集中管理する目的で利用しました。
`ECS`からこちらのパラメータを参照する形で設定しています。

似たようなサービスとして`Secrets Manager`というものがあります。
こちらはパラメータを定期的に更新したり、ポリシー(IAM)を細かく設定したりできるようです。
従量課金制のため、`Systems Manager`よりはお金がかかります。
`Systems Manager`はスタンダードパラメータの場合は無料です。有効期限やポリシーが設定できるアドバンスドパラメータの場合は有料となります。

***

### CI/CD

フロントエンドは`Amplify`、バックエンドは`CircleCI`を採用しました。
フロントエンドに関しては、上記の通りホスティングに`Amplify`を使ったため、標準機能としてのCI/CD環境を利用しました。
バックエンドに関して、`CircleCI`を選択した理由ですが、知名度が高いSaaS型CI/CDツールだったためです。
あまり技術的な理由はなく、`Github Actions`や`AWS CodeBuild`でも良いかなと思います。
Githubへのpushやmerge時に、自動テストと本番環境へのデプロイが動くよう設定していました。
UIが優れており、今どのフェーズを実行中なのか(テスト中なのか、ビルド中なのか、デプロイ中なのかなど）がわかりやすかった印象です。

##### その他の選択肢

`Github Actions, AWS CodeBuild`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [CircleCI実践入門──CI/CDがもたらす開発速度と品質の両立](https://www.amazon.co.jp/CircleCI%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80CI-CD%E3%81%8C%E3%82%82%E3%81%9F%E3%82%89%E3%81%99%E9%96%8B%E7%99%BA%E9%80%9F%E5%BA%A6%E3%81%A8%E5%93%81%E8%B3%AA%E3%81%AE%E4%B8%A1%E7%AB%8B-WEB-PRESS-plus-ebook/dp/B08H51JHS1)  | 書籍 | CircleCIの使い方のほか、CI/CDのメリットについても解説してくれています。 |
| [AWS ECR/ECS へのデプロイ(公式ドキュメント)](https://circleci.com/docs/ja/2.0/ecs-ecr/)  | Web | CircleCIは公式ドキュメントがめちゃくちゃわかりやすかったです。困ったから公式を読みましょう |

### その他

#### 開発環境

最初はローカルPC環境で開発していましたが、途中から`Docker`上で開発・検証環境を立ち上げました。
当初から本番環境にはコンテナを採用するつもりでしたし、開発環境もコンテナで作る予定でした。ですが初めて扱う技術が多いため、影響範囲を切り分けやすくする目的で、序盤はローカルPC環境で開発していました。**アプリ側の問題なのか、コンテナの設定による問題なのかを切り分ける**、ということですね。

メリットを一番実感したのは、途中でRubyをバージョンアップした時です。
ローカル環境はグローバルにインストールされていたgemの影響でエラーが発生し、かなり苦戦してしまいました。
ですがDocker環境は異なるバージョンのRubyのイメージファイルで構築し直すだけなので、全く問題なく実施できました。

やはり本番環境と同等の環境を構築できるのは大きなメリットですね。

また複数のコンテナイメージを構築しているため、開発環境では`docker-compose`を使っています。
例えば、バックエンドは以下のイメージを使っています。このような複数のイメージを一括で管理できるのが、`docker-compose`の良いところですね。

- Ruby
- MySQL
- nginx
- mailcatcher(テスト用メールサーバー)

##### その他の選択肢

`ローカル, VM(仮想マシン)`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2-ebook/dp/B07GP1Q3VT)  | 書籍 | 私はここからDockerを学習し始めましたが、結構初心者には難しい印象でした。もっと初学者向けの書籍があるかもしれません。 |
| [Docker公式チュートリアル](https://docs.docker.com/get-started/)  | Web | 上の書籍で学習してから実際の開発まで時間が空いたので公式チュートリアルで復習しました。 |

#### バージョン管理

ここは`git`一択でした。サービスとしては`Github`を利用しています。
前職では`svn`を利用していましたが、分散型バージョン管理システムが今は主流です。
あと初心者は`SourceTree`などのGUIツールを使ったほうがいいと思います。慣れてきたらコマンドでできるようになるといいですね。

##### その他の選択肢

`svn`

##### おすすめの学習方法

| 対象 | 媒体 | 補足 |
|:-|:-:|:-|
| [改訂2版 わかばちゃんと学ぶ Git使い方入門〈GitHub、SourceTree、コマンド操作対応〉](https://www.amazon.co.jp/%E6%94%B9%E8%A8%822%E7%89%88-%E3%82%8F%E3%81%8B%E3%81%B0%E3%81%A1%E3%82%83%E3%82%93%E3%81%A8%E5%AD%A6%E3%81%B6-Git%E4%BD%BF%E3%81%84%E6%96%B9%E5%85%A5%E9%96%80%E3%80%88GitHub%E3%80%81SourceTree%E3%80%81%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E6%93%8D%E4%BD%9C%E5%AF%BE%E5%BF%9C%E3%80%89-%E6%B9%8A%E5%B7%9D-%E3%81%82%E3%81%84/dp/4863543433)  | 書籍 | 漫画形式で理解できるので、わかりやすく非常におすすめ |

## 反省点

ここまで読んでいただき、ありがとうございます。
この項目ではポートフォリオに関する私の反省点を記載します。興味のない方は飛ばしていただいて構いません。

散々書いてきましたが、開発期間の問題で妥協せざるを得なかった点がたくさんありました。
一重に見積もり能力の不足が原因です。
機会があれば、見送った機能を追加したいなと思います。

### 作成予定だったが見送った主な機能

- プロジェクトに他ユーザーを招待する機能
- タスクの一覧検索機能
- 1つのノートにN個のタスクを設定する機能
- ノートの変更履歴を確認する機能
- タスクの詳細項目を入力する画面

## おわりに

かなりの長文となってしまいました。ここまで読んでいただいた方、本当にありがとうございます。
多くの苦労がありましたが、私は一からアプリを作る経験ができて良かったと思っています。
技術選定のポイントは多々あると思いますが、**自分の中で根拠を見出すことが大切**なのだと思います。

また私は完全に独学で作成しましたが、**メンターサービス**を利用するのも有りだと思いました。
嵌っている時間が長すぎるともったいないですし、経験者の知識をお借りするのは実務でも普通のことですので。

最後に個人的なお話ですが、Web系企業への転職が決まりました！　<del>次は技術的な観点ではなく、転職活動記録として苦労話でも書こうかな思います。</del>
**[追記]2020年7月18日** 転職活動記録を書きました。
https://zenn.dev/momonga11/articles/8661a67aed79df


一人でも多くの方の参考になれば嬉しいです！

ちなみにtwitterもやっております。どうぞお気軽にフォローください。
【twitterアカウント】
https://twitter.com/momonga11_d