はじめに
プログラミング歴半年(独学)の実務未経験者がSPAなポートフォリオを制作しましたので紹介していきたいと思います!
今後もアップデートしていくのでフィードバックなど頂けますと嬉しいです。
記事の最後には、お世話になったWebサイトや教材をまとめておきましたので参考になれば幸いです。
作者のスペック
年齢は27歳で今までにプログラミング経験は全くなし。
サーバーサイドエンジニアを目指してプログラミング学習中の初学者です。
本記事を執筆している時点でプログラミング学習期間は半年。(2021/1/29時点)
ポートフォリオに関わる技術のキャッチアップをしながら約4ヶ月程かけて完成させました。
ポートフォリオ制作に着手した時点では、ProgateとRailsチュートリアルを終えた程度の実力。
至る所に詰みポイントがありひたすらググりまくって問題解決してました。(Google先生は神)
アプリの概要
制作したアプリケーションがこちら。
https://gadget-community.com(3/28 公開停止しました)
『ガジェコミ!』はガジェット好きが集まれるSNS型のWebアプリケーションです。
簡単に言ってしまえば『Twitterクローン』に近いものなので、SNSに必要な機能を重点的に実装済み。
スマホ利用を想定しているのでモバイルからも気軽にお試し下さい!(ゲストログイン有ります)
トップページ
レスポンシブ対応
スマホ利用も想定したUI設計。
Ajax処理
ネストした要素でもAjaxに動作します。
例) 『コメントアイコンをタップ → コメント欄を表示 → 既にあるコメントに返信』
ポートフォリオに使用した技術
各バージョン
- Ruby 2.7.1
- Rails 6.0.3.4
- nuxt 2.14.6
- @nuxtjs/vuetify 1.11.2
- Docker 19.03.13
- docker-compose 1.27.4
- Terraform 0.14.3
フロントエンド
名称 | 説明 |
---|---|
Nuxt.js (SSR mode) | フロントエンドフレームワーク |
Vuetify | UIコンポーネント |
Firebase Authentication | JWTを用いたログイン・ログアウト |
-
Vuetifyコンポーネントを導入することで、スマホ利用を想定したレスポンシブデザインを実現。
-
Vuexストアでステート管理。
-
個人情報(パスワード)は、外部API(Firebase Authentication)に保存する仕組みで、外部APIで発行されるJWTをCookieに保存してログイン・ログアウト機能を実装しました。
-
未ログイン状態でアクセスして欲しくないページ( /users/editなど )へのアクセス対策には、Nuxt.jsのmiddlewareを活用することで自動的にリダイレクトするようにしました。
-
ログイン状態でアクセスして欲しくないページ (ログインページ, 新規作成ページ) へのアクセスも同じくリダイレクトします。
バックエンド
名称 | 説明 |
---|---|
Rails (API mode) | APIサーバーとして利用 |
PostgreSQL | データベース |
-
RailsはAPIサーバーとして利用しており、フロントエンドコンテナからのリクエストに対してJSONデータを返しています。
-
画像データはActiveStorage経由でS3バケットに保存。
-
その他のデータはRDSに保存。
-
個人情報(ログインパスワード)は外部API(Firebase Authentication)にのみ保存しており、バックエンド(Rails)には保存されません。
テストコード
名称 | 説明 |
---|---|
Jest | フロントエンドテスト, Vuexストアの動作を少しだけ |
RSpec | バックエンドテスト, バリデーションとアソシエーションのテストのみ |
- CodePipelineのTestステージで実行するテストコードです。
インフラ
名称 | 説明 |
---|---|
ECS Fargate | サーバーレスな本番環境, オートスケール |
CodePipeline | CI/CD環境 |
RDS | 本番用DB(PostgreSQL) |
Docker, Docker-compose | コンテナ環境 |
Github | バージョン管理 |
Terraform | 本番用インフラをコード管理 |
-
ローカル開発環境からデプロイまで一貫してDockerを使用。
-
ALBを通すことで常時SSL通信化。
-
CodePipelineは、 『Sourceステージ => Testステージ => Buildステージ => Deployステージ』の順で実行され、Testステージで問題が発生した場合は当該ソースでのDeployは実行されません。
-
本番環境の環境変数については SSM で管理。『システム環境変数 => Terraform => SSM => 各AWSサービス』というフローで環境変数を受け渡しています。
インフラ構成図
インフラの全体像をまとめたものがこちら。
RDSにはPostgreSQLを採用し、画像を除いたデータを保管。
画像データはS3に保管しています。
ER図
一貫性のあるテーブル名称を意識しました。
アプリの機能紹介
0. 機能一覧
機能名 | 説明 |
---|---|
ユーザー機能 | 新規登録、登録内容変更、アバター登録、ログイン、ログアウト、フォロー |
つぶやき機能 | 投稿、編集、削除、画像複数枚登録 |
つぶやきコメント機能 | つぶやきに対してコメント投稿、コメントへのリプライ投稿、削除、画像複数枚登録 |
つぶやきいいね機能 | つぶやきをいいねできる、マイページのいいねタブにいいねしたつぶやきを一覧表示 |
掲示板機能 | 質問掲示板、雑談掲示板の作成、編集、削除、画像複数枚登録 |
掲示板コメント機能 | 掲示板に対してコメント投稿、コメントへのリプライ投稿、削除、画像複数枚登録 |
私物ガジェット機能 | 登録、編集、削除、画像複数枚登録 |
フィード機能 | つぶやき新着表示、タイムライン表示、タグフィード表示 |
タグ管理機能 | つぶやき・掲示板・私物ガジェットにはタグを登録可能、タグをタップしてタグ詳細ページを表示、タグ詳細ページではタグを含むコンテンツを表示 |
検索機能 | 各コンテンツを検索可能 |
通知機能 | つぶやきにいいね・コメント、掲示板にコメント、他ユーザーからフォローされると通知を表示 |
管理者モード | Godmode のトグルスイッチをONにすると、一時的に管理者権限が有効化、各コンテンツの削除メニューが表示される |
1. ユーザー機能
登録・編集・削除
メールアドレスとパスワードを入力するだけでアカウント作成できます。
メールアドレス確認機能は未実装。
VeeValidateを使用してフォームにバリデーションを設定しています。
詳細設定ページで登録情報を編集できます。
ユーザーにはアバターを設定できます。
アバター画像は各コンテンツで表示されます。
2. つぶやき機能
投稿・編集・削除
つぶやき編集は即時反映されます。
つぶやき削除は即時反映されます。
タグ付け
つぶやきにはタグを複数登録できます。
コメント
つぶやきにはコメントすることができます。
コメントに返信できます。
コメントは削除のみ可能です。編集機能はありません。
親コメントを削除すると子コメントも削除されます。
いいね
つぶやきにいいねできます。
3. 掲示板機能
作成・編集・削除
掲示板作成は即時反映されます。
掲示板編集は即時反映されます。
掲示板削除は即時反映されます。
タグ付け
掲示板にはタグを複数登録できます。
掲示板タイプ
『雑談』『質問』を選択できます。
コメント
掲示板にはコメントすることができます。
コメントに返信できます。
コメントは削除のみ可能です。編集機能はありません。
親コメントを削除すると子コメントも削除されます。
4. 私物ガジェット機能
登録・編集・削除
自分の私物ガジェットやお気に入りアイテムを登録できます。
登録したガジェットは一覧ページでは『みんなのガジェット』として新着表示されます。
ガジェット編集は即時反映されます。
ガジェット削除は即時反映されます。
タグ付け
私物ガジェットにはタグを複数登録できます。
5. フィード機能
つぶやきを一覧表示します。
無限スクロールで順次読み込みます。
<タブによって表示する内容が異なります>
- 新着順 => 全てのつぶやきを新着順で表示
- タイムライン => フォロー済みユーザーのつぶやきのみ新着順で表示
- タグフィード => フォロー済みタグを含むつぶやきのみ新着順で表示
6. タグ管理機能
タグをフォローすることができます。
タグフィードに表示したいタグをフォローします。
つぶやき・掲示板・私物ガジェットはタグ付けすることができます。
タグをタップするとタグ詳細ページに遷移し、タグを含むつぶやき・掲示板・私物ガジェット・フォローしているユーザーの一覧を表示します。
7. 検索機能
検索ページでは、検索フォームに入力した内容に合わせて結果がリアルタイムに表示される機能を実装しております。
8. 通知機能
つぶやき・掲示板・ユーザーフォローにおいて、イベントが発生すると通知が表示されます。
新着通知
新しい通知が発生すると、ヘッダー内のベルアイコンにバッジが表示されます。
タップすると新しい通知がリスト表示され、通知をタップするとイベント発生元へ画面遷移します。
通知一覧
通知一覧をタップすると一覧ページへ画面遷移します。
通知一覧ページでは、今まで受け取った全ての通知を表示します。
9. ゲストユーザー機能
■追記(2/19)
ゲストユーザー機能の仕様を変更しました。
変更点)ブラウザ再読み込みでログアウトするようになりました。
→ RailsAPIからユーザー情報を取得して、Nuxt.jsのVuexストアに値を保存しているため。
→ FirebaseのJWTをCookieに保存したログイン・ログアウトの永続化は、ゲストユーザーからは除去しました。
→ ログイン状態だとFirebaseAuthenticationユーザーを削除する為に必要な値がデベロッパーツールから確認できてしまうため。
→ FirebaseAuthenticationユーザーを削除すると、ゲストユーザーログイン機能が動作しなくなるため。
ユーザー専用機能を簡単に利用できるように、ゲストユーザーログイン機能を実装しています。
『ゲストユーザーとしてログイン』をタップするだけです。
未ログイン状態でユーザー専用機能にアクセスすると、ゲストユーザーログインを促すダイアログを表示するようにしております。
10. God mode
(1/31 追記)
・削除を実行できないように修正しました。
・管理メニューを確認するための機能として残します。
(2/3 追記)
・特定のメールアドレスを持つユーザーのみ削除を実行できるように修正しました。
一時的に管理者権限を有効にするモードです。(管理者という概念が存在することを確認して頂くためのモードです。)
DB内 の Userモデルの adminカラム の true/false で 各ユーザーの管理者権限を管理しておりますが、God modeではVuexストアの値を一時的に変更して管理者権限を有効化しています。(DB上には保存されないのでブラウザ再読み込みでfalseに戻ります。)
つぶやき・掲示板・私物ガジェットにはそれぞれ『管理メニュー』が設定されており、作成者本人にのみ表示される仕組みです。
God mode を有効化にすると他のユーザーが作成したコンテンツでも『管理メニュー』を表示するようになり、『削除のみ』実行可能となります。
制作を終えてみて
ポートフォリオのアップデートは今後も行いますが、いったん区切りがついたのでホッとしています。
制作中に苦労したポイントをまとめてみると以下の内容で、主に初期学習のタイミングで壁が何度も現れました。
壁 | 内容 |
---|---|
フロントエンドとバックエンドを分離した開発環境の構築 | 仮想コンテナの基礎知識やポートフォワーディングでつまりました。初めからdocker-composeを使うことをオススメします。 |
環境変数の受け渡し | ローカル環境、本番環境のインフラ構成に合わせて環境変数の渡し方に工夫が必要でした。 |
Vuetifyモジュールの導入 | Nuxt.jsの初期セットアップでVuetifyを選択するとエラー発生。VuetifyなしでNuxt.jsをセットアップ + 後からVuetifyを導入 + おまじないが必要で詰みました。 |
SSRモードで動作するNuxt.jsのライフサイクル | SSRでSPA用コードを実行するとライフサイクルが一部違うので正常に動作しません。 |
AxiosモジュールのSSRモードでの挙動 | SPAとSSRではAxiosのエンドポイントの設定に違いがあり詰みました。 |
Firebase Authenticationの導入 | SSRモードでの解説記事が少なく、動作させるまでに苦労しました。 |
SSRモードでは動作しないプラグイン | ポートフォリオで利用した『@johmun/vue-tags-input』がSSRモードでは動作しなかったので、特別なおまじないが必要でした。 |
親コンポーネントと子コンポーネントのデータ受け渡し | props, emitの概念の理解に苦戦しました。 |
Vuexストアの扱い方 | 断片的な解説記事が多くて理解するのに時間が掛かりました。 |
終わらないN+1対策 | アソシエーションの絡んだデータ取得をするたびに苦労しました。 |
ECS Fargateでのインフラ構築 | FargateはSSHできないのでエラーログの取得やトラブルシュートに手間取りました。CloudWatchなどを利用して確実にログを取れる環境を作らないと、どこに問題があってコンテナが動いていないのか判断できなくて詰みます。 |
特に厳しかったのがECSデプロイでして、途中何度も諦めそうになりましたが何とかやり終えることができました...。(インフラ難しい)
何とか形になったものの、書いているコードは実務レベルから比べると『その場しのぎ』程度だと思いますし、
プログラミングにおける基礎知識が抜けていると思い知らされる場面も多々ありました。(特に学習初期の理解力)
正直なところ、Nuxt.js や Rails という『ツール』を何となく使えている、というのが現時点での実力だと思います。
今後について
ポートフォリオが完成したので就活を始めるために準備を進めています!
就活以外では、課題である基礎力を伸ばすために基本情報技術者やJavaSliverなどの取得を目指して資格勉強も進めていくつもりです。(オススメ教材などあれば教えて欲しいです)
ただのポートフォリオ紹介記事ですが、最後までお付き合い頂きましてありがとうございました!
関連リンク
お世話になった書籍や教材
ポートフォリオ制作中に何度もお世話になった資料一覧です。
これがなければ完成できていなかったので本当に感謝しています。ありがとうございました!
媒体 | 資料名 | 学習内容 |
---|---|---|
Web | Progate | Ruby, Rails, HTML, CSS, JavaScript...などの基礎を学習 |
Web | Railsチュートリアル | いわずもがな、Railsの基礎、Herokuデプロイ、AWS S3、GitHubの扱いなどを学習 |
Web | JavaScript Primer | DOM操作以外のJavaScriptの基礎を学習 |
Web | Rails + Nuxt.js + Docker なアプリを作ってみよう | 神記事です。めちゃめちゃ参考になりました。ただしSPAモードなのでSSRモードで制作する場合は工夫が必要。 |
Web | 独学プログラマ (Docker+Rails6+Nuxt.js+PostgreSQL)=>Heroku 環境構築~デプロイまでの手順書 | 神記事です。特に環境構築の手法がめちゃめちゃ参考になります。 |
Web | Pikawaka | Railsの基礎はここ見れば大体全部載ってます。マジでわかりやすくて助かりました。 |
Web | SSRモードのNuxtでのFirebase認証 | この記事とGitHubリポジトリがなければ実装するの諦めてました。本当にありがとうございます。 |
Web | b1tblog | Vue.jsの解説記事が多数掲載されています。 |
書籍 | たのしいRuby | Rubyの基礎を学習 |
書籍 | Ruby on Rails速習実践ガイド | Railsでよく使うコマンドやRailsの基礎を学習 |
書籍 | プロを目指す人のためのRuby入門 | 実践的なRubyについて学習 |
書籍 | Rubyによるクローラー開発技法 | Rubyだけでスクレイピングアプリを作れます。学んだ基礎知識をアウトプットするために使用しました。 |
書籍 | Nuxt.jsビギナーズガイド | Nuxt.jsの基礎学習。Vue.jsの経験がないと難しいかも。 |
書籍 | 速習Vue.js3 | Vue.jsの基礎学習。単一コンポーネント形式のサンプルが少ないので、これだけでは不十分かも。 |
書籍 | 実践Terraform AWSにおけるシステム設計とベストプラクティス | 神本。これがなければECSデプロイできませんでした。感謝しています。 |
書籍 | はじめての人のためのTerraform for AWS | Terraformを全く触ったことない人向けの書籍。サンプルコードがちゃんと動作するので感じを掴むのに最適。 |
書籍 | CircleCI実践入門 | CI/CDってなに?という状態から勘所を掴むために使用。結局CodePipelineで実装したけど自動テストの雰囲気が掴めて良かった。 |
書籍 | Amazon Web Services 基礎からのネットワーク&サーバー構築 | AWSの基礎学習にぴったり。EC2での解説なのでECSについては別途学習する必要あり。 |
書籍 | Docker/Kubernetes実践コンテナ開発入門 | Dockerの基礎学習。初心者向けの章節まで読めば十分でした。 |
書籍 | ゼロからはじめるデータベース操作 | 実践的なSQLを学習。 |
書籍 | Webを支える技術 | ネットワークの概念がイマイチ理解できてないときに使用。 |
書籍 | GitHub実践入門 | GitHubの基礎学習 |