8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【完全SPA】独学・未経験者が「防災啓発」アプリを開発した話(2/2)【Rails/Nuxt.js/AWS/Docker/CircleCI/Terraform】

Last updated at Posted at 2022-10-29

記事の内容

業界未経験がWeb系エンジニアになるべく作成したポートフォリオに関して、以下の情報を2つの記事に分けてまとめます。

  1. ポートフォリオの紹介
  2. 利用してもらった感想 と フィードバックによる改善
  3. 技術選定理由 と 使用した教材の紹介
  4. 反省 と 今後の課題

本記事では、 3 と 4 について記事を書かせていただきました。
1 と 2については、こちらに書いております。
最後まで読んでいただけると嬉しいです!

技術選定理由と使用した教材

こちらにまとめた技術に関して、それぞれの選定理由と私が実施した学習方法について、説明します。
また、各技術の基礎知識について、私なりにわかりやすくまとめたQiitaの記事も載せておくので、参考にしていただけると幸いです。


基礎知識

まず大前提として、以下の理由により、「なぜコンピューターは動くのか」などのコンピューターサイエンスやLinux等の基礎知識は必須になると感じました。

  • デバッグが開発の多くを占める中、言語やフレームワークがどのように動いているかが分からないこととなり、デバッグに多くの時間を要してしまう。
  • 技術の流行り廃りが激しく移り変わる中、1つの言語やフレームワークに固執することは非常に危険であるため、これらの枯れた技術を優先的に学び、各言語やフレームワークに応用するべきである。

参考:なぜ、プログラミングではなく「コンピュータサイエンス」なのか

使用した教材

書いた記事

アプリケーション全般

Webアプリ基礎

アプリケーションを作成するに当たって、はじめにWebアプリケーションで作成するべきか を検討しました。
以下の理由より、Webアプリケーションが適していると判断しました。

  • ネイティブアプリは、端末上で高速で利用できるなどのメリットがありますが、App StoreやGoogle Playなどの特定企業のアプリケーションストアを介すため、審査が厳しいため公開すらできない場合がある。
  • スマートフォンでの利用もありだが、災害時役立つ記事作成機能はPCで書く機会が多いため、Web優先となった。
  • スマートフォンで利用したほうが便利な機能もあるが、PWAの設定をすればWebアプリケーションでありながら、ネイティブアプリのように使用できるため、問題ないと考えた。
使用した教材

書いた記事

Webアプリの通信方式

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

  • 防災タスクや災害時役立つ記事などを閲覧するため、頻繁にページ遷移することが予想される。
  • そのため、ページ遷移の際に時間を食わず、ユーザーがより心地よくWebサイトを利用してもらうため。
  • SSRよりは学習コストが低い。
使用した教材

開発方法

以下の理由により、フロントエンドとバックエンドを完全分離して開発しました。

  • 分離することで、UI/UXについてはフロントエンド、サーバー側はデータ操作に専念することができ、不具合があったときもどこで障害が発生しているのかが明確になる。
  • バックエンド側にUIを持たないことで、同じ情報を別のデバイス向けに開発することになった際にも再利用しやすくなる。

参考:フロントエンド・バックエンドを分けて開発する8つの利点

開発環境

以下の理由により、Dockerを使用したコンテナ環境を採用しました。

  • OS、ライブラリ、アプリケーションをひとまとめのパッケージにして配布できるため、開発環境を簡単に用意できる。
  • 開発環境・本番環境の統一ができる。
  • 今回は一人だったが、複数人で開発する場合にメンバー間の開発環境を統一することもできる。

なお、複数のコンテナイメージを構築しているため、開発環境ではdocker-composeを使っています。

使用した教材

書いた記事

バージョン管理

ここはGit一択でした。サービスとしてはGithubを利用しています。
私ははじめSourceTreeを使い、分散型バージョン管理のイメージが付くようになってからGitコマンドを使って開発しました。
SourceTreeなどのGUIツールを使うとイメージがしやすいため、おすすめです。

使用した教材

書いた記事


フロントエンド

言語

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

使用した教材

Progateドットインストールを利用。

JavaScriptフレームワーク

結論としては、SPAで構築するため、Vue.jsを採用しました。

  • まず、React, Vue.js, Angularが候補となりました。

  • Angularはこの中だと大規模アプリ向けのため、最初に除外しました。

  • 次に、ReactVue.jsを比較した結果、以下の理由により、Vue.jsの方が学習コスト低いと判断したため、Vue.jsを採用しました。

    • ReactVue.jsもコンポーネントという単位で部品を定義しますが、ReactJSXはJavaScriptのコードの中にHTMLのタグが埋め込まれている形のため、HTML初心者には少し難しいと感じました。
    • 一方、Vue.jsはHTML、CSS、JSの記述場所がそれぞれ分かれており、フロントエンド初心者やデザイナーさんも読めるような構成になっていると感じました。
  • また、Vue.js単体でなく、Nuxt.jsフレームワークを採用した理由は、以下などの機能があり、Vue.jsをより使いやすくする機能を持っているため、開発効率が良くなると考えたため、採用しました。

    • Vue.jsでは手動で設定する必要があるルーティングが、Nuxt.jsでは特定のディレクトリにファイルを追加するだけで自動的に設定される。
    • アプリケーション全体の状態を管理できるストアを持っている。
  • なお、学習時及び開発開始時のVue.js(Nuxt.js)のバージョンは2系で学習してしまったので、3系ではございません。

  • 2023年末にVue.jsのバージョン2系のサポートが終了しますので、今から学習する方は3系を選択することをおすすめします。

参考:2022-06-21のJS: Internet Explorer 11のサポート終了 - JSer.info

使用した教材

CSSフレームワーク

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

使用した教材

API通信

  • HTTP通信を理解できるため、RESTを採用し、JSONフォーマットでフロントエンド-バックエンド間の通信を実施しました。
使用した教材


バックエンド

言語

かなり個人的な理由になりますが、以下の理由によりRubyを採用しました。

言語 理由
Ruby 日本発の言語であり、日本語のドキュメントが豊富。かつスタートアップ企業で多く採用されており、求人数も多い。
Python 機械学習をやるのであれば採用するべきだが、今回は違うことに加え、日本での求人数も考慮し、優先度は低かった。
PHP 求人数は多いが、古くから稼働しているシステムも多く、新しく学ぶ言語としては優先度は低かった。

※もし静的型付言語で実装する場合は、GoKotlinが有力候補だと思います。特にGoは最近のスタートアップ企業では多く採用されている印象です。

使用した教材

Progateドットインストールを利用。

筆者がQiitaで出版後に出たRubyのバージョンによる差異を補足されていますので、要チェックです。

フレームワーク

Ruby on Railsを採用しました。
Rubyといえばこれ。のようなイメージがあります。
比較的速く・簡単に実装できるため、中小規模のアプリを短期間で作成することを目指すのであれば最適ではないかと思います。

使用した教材

データベース

以下の理由により、MySQLを採用しました。

  • まず、テーブルとして構造化されたDBの方が開発、運用のしやすさにメリットがあると思い、RDBMSを選択しました。
  • 次に、MySQLを選んだ理由ですが、大きく以下のようなものがあります。
    • シンプルかつ必要十分な機能を備えたRDBMS。作成するアプリに必要な機能を全て満たしている。
    • PostgreSQLは分析系の機能が豊富だが、今回のポートフォリオでは不要だった。
使用した教材

書いた記事

Webサーバー

  • Apachenginxのどちらを採用するか迷いましたが、大量アクセスに関する処理においてはnginxに軍配が上がるため、nginxを採用しました。
  • 計算処理に時間がかかるAPI処理などがあれば、Apacheを検討した可能性もあります。
使用した教材

APサーバー

Rails5.2からUnicornではなくPumaが標準のAPサーバーになり、あえてUnicornに変える必要もないと思ったため、Pumaを採用しました。

使用した教材

認証系

  • 認証系は利用者の情報に直接関わるため、セキュリティ上の問題点などをさまざま検討し、悩みましたが、ブラウザの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サーバーをステートレスにできる、ということだと判断しました。
IDasS
  • Firebase AuthenticationやAuth0などのIDasSのサービスを使うことも検討しました。
  • しかし、IDaaSを使った場合は、テスト環境の構築が容易ではなくなると思い、見送りました。
検討結果
  • devise_token_authというgem(Rubyのライブラリ)を使って、トークン認証を実装することに決めました。
  • 理由は、開発期間の問題とポートフォリオとしてどこまでの機能を盛り込むかを考えた結果、以下の利点があったためです。
    • devise_token_authを使えば、メール認証によるサインアップやパスワードリセット、パスワード連続入力失敗によるアカウントロックなどの機能が標準で実現できます。
    • 今回は実施しなかったですが、OAuth認証もサポートされています。
    • また、日本語の解説記事も豊富だったことも大きな利点でした。
使用した教材

インフラ

インフラ図

AWS

以下の理由により、AWSを全体的に採用しています。

  • 世界で最も多く利用されているクラウドサービスであり、ドキュメントが豊富。
  • GCPMicrosoft Azureがその他の選択肢となると思いますが、以下の理由で対象から除外しました。
    • GCPはBigQueryなどの分析系の機能が充実しているが、今回のポートフォリオには不要だと判断した。
    • Microsoft AzureはMicrosoft系の技術との親和性が高いが、今回はMicrosoft系の技術を採用していないため、メリットが大きくない。
使用した教材

書いた記事

Terraform

以下の理由により、Terraformでインフラ全体をコード化しました。

  • Gitによるバージョン管理に対応していること。
  • 今後同様のインフラ環境を構築する際の工数削減効果がある。
使用した教材

※この記事を参考に Rails + Nuxtjs に応用して実装しました。

CI/CD

自動テストはCircleCIを採用し、自動デプロイはAWS CodeBuildを採用しました。
Githubへのpushやmerge時に、CircleCIによる自動テストを実施し、masterブランチにmergeした時にAWS CodeBuildによる本番環境へのデプロイが動くよう設定しました。

  • テストにCircleCIを選択した理由は、単純に知名度が高いSaaS型CI/CDツールであり、インフラを構成する前から使用していたためです。
  • デプロイにAWS CodeBuildを採用した理由は、他のインフラ環境をAWSで実装したため、デプロイにもAWSのサービスを使ってみたいと感じたことと、CircleCI以外のCI/CDツールも使ってみたいと感じたためです。
使用した教材

反省

実装しきれなかった機能

開発期間と見積もり能力の不足が原因で、以下の機能を実装しきれませんでした。
機会があれば、見送った機能を追加したいと思います。

  • 防災イベントを主催する機能
  • 防災イベントに招待・参加する機能
  • 防災イベント参加者用のコミュニティ機能
  • 防災イベントに参加した人向けの匿名アンケート機能
  • 通知ON/OFFの切り替え設定

など

メンターサービスの利用

私は完全に独学で作成しましたが、以下の理由によりメンターサービスを利用するべきだと思います。

  • 嵌っている時間が長すぎるともったいない。
  • 経験者の知識をお借りするのは実務でも普通だと思う。
  • 質問力を身につけるため。

今後の課題

見送った機能を実装

  • 先ほどの反省点であったとおり、防災イベントに関する機能や通知設定機能を実装していきたいと思います。

テストが不十分

  • ユーザーに関する部分のテストは重要なので優先して書きました。
  • しかし、防災タスクに関するテストはフロントエンド、バックエンドともに不十分なので、今後書いていきたいと思います。

リファクタリング

  • 機能を実装することを最優先としたため、フロントエンドからバックエンドにAPIリクエストを投げる際のエラー処理など、複数回同じようなコードを書いている箇所が散見される。
  • テストの追加と並行してリファクタリングしていきたいと思います。

Vue.jsを3系に更新とNuxt Bridgeへの移行

  • 既存のNuxt 2 プロジェクトに関しては、Nuxt Bridgeを経由してNuxt 3 にUpgradeすることを公式が強く推奨しています。
  • また、動作に関してもNuxt 3 よりもNuxt Bridgeの方が安定していることを公式が発表しています。
  • ですので、既存のNuxt 2 プロジェクトに関しては、Nuxt Bridgeで動作を確認しながら、Nuxt 3系が安定してきたらUpgradeするのが良いのではないかと思うので、今後移行していきたいです。

TypeScriptやComposition Apiの導入

  • SPAで配信する際に、ほぼ必須レベルのTypeScriptですが、導入しておりませんでした。
  • 理由は、技術的なメリデメで判断したわけではなく、単純に学習コストの問題により見送っておりました。
  • JavaScriptの基礎を学んだところだったので、そこからさらにTypeScriptになると、開発着手時期が遅れてしまうため、JavaScriptで行くことにしました。
  • 余力ができたら、今後TypeScriptを導入していきたいと思います。

参考:TypeScriptとは?JavaScriptとの違いも解説!

  • また、TypeScriptを導入するとなると、相性が良いと言われているComposition Apiも導入を検討する必要があるかなと感じております。

参考:Vue3のCompositionAPIがOptionsAPIよりも優れている理由をVue3エンジニアが解説!

おわりに

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

同じような境遇の方に参考になれば嬉しいです!

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?