未経験者がLaravelでポートフォリオを作成した話【学習開始〜AWSデプロイまで】

## 簡単に自己紹介
・東京で構造設計をやっている30代前半
・健康好きで趣味はアンチエイジング
・転職活動1ヶ月で自社開発企業に内定

## どんなアプリ？ 何ができる？
ひとことで言うと
<b>「パレオダイエッター(という健康法をやってる人)向けのコミュニティ＋計算機能ツール」</b>
です。
<img alt="画面キャプチャ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675596/852c662e-1760-d1e1-ff71-a55ca1ef44e3.gif" width=75%>

基本的なユースケースとしては、
　`・「ユーザー登録/ログイン/プロフィール編集」`
　`・「文字や画像を投稿・編集/いいね/コメントで交流」`
　`・「筋肉をつける・腹筋を割るための目標カロリー算出→マイページ登録」`
という感じになります。

もう少し機能を細分化すると、
　・ユーザー登録・ログイン機能・ゲストログイン機能
　・プロフィール編集機能（自己紹介文とアバター画像）
　・投稿作成機能（モーダル画面,文字数カウント,画像投稿）
　・コメント機能
　・投稿とコメントの編集・削除機能
　・いいね機能（Ajax利用,リレーション数取得）
　・効率よく筋肉をつけるための目標摂取カロリーおよび三大栄養素の計算機能（Ajax）
　・最速で腹筋を割るための目標摂取カロリーおよび三大栄養素の計算機能（Ajax）
　・投稿の検索機能とページネーション
といった具合です。

## 使用技術と環境は？
・言語：PHP7, JavaScript(jQuery), Bootstrap, HTML, CSS(Sass)
・フレームワーク：Laravel7
・DBMS：MySQL
・インフラ：AWS（EC2,RDS,ELB,S3,Route53,ACM）
・Webサーバー：Apache HTTP Server, Amazon Linux OS2 
・開発環境：ローカル環境(MacOS), VSCode
　（本当はDockerなども導入したかったですが..現在勉強中です）

## 作った背景と目的
ポートフォリオを作った理由は、
　①転職時に必要不可欠と考えるため
　②ゼロからアプリ開発を経験することで成長したいため
　③必要とされる機能を実装して価値を生み出したいため
の3つです。

#### ①転職時に必要不可欠と考えるため
職務経歴や経験で充分にスキルを示せる場合は別ですが、そうでない場合は何かモノを作っていないとスキルを定量的に示すことができないかなぁと思います。
これは、もし自分が評価する側だったら「勉強してますが何も作ったことはありません！」だと、その人がこれから活躍していく姿をうまくイメージするのは難しいと考えるためです。

#### ②ゼロからアプリ開発を経験することで成長したいため
Progateなどの教材はとても分かりやすいですが、環境構築や設計、エラー解消といった場面に遭遇することはありません。
また書籍や動画の教材もそうですが何か問題に遭遇してもそこに答えのコードがあるので、実際に<b>ロジックを考えることはほぼ無い</b>と言えます。(書いてあるコードを再現すれば動く)

やはり実際に`「こんなものを作りたい」`→`「そのために必要なことは？」`→`「問題が発生」`→`「試行錯誤」`→`「解決！」`といったプロセスを経験することで得られる学びは計り知れないほど大きいと思います。

#### ③必要とされる機能を実装して価値を提供したいため
人に貢献することが好きなので、アプリ制作をするなら`誰かに価値を提供できるもの`にしたいと思いました。

しかし実際に人に利用してもらえるサービスを提供するとなるとマーケティングや運用保守の要素がそれなりに必要になりますし、初学の段階で「誰かに使ってもらうこと」に期待しすぎても学習の挫折要因になりかねないとも考えます。

そのため`「自分でこんなのがあったら良いな」`を少しずつ実現することを主な目的のひとつとしました。
具体的には、
　<b>「パレオダイエットを実践する人って少ないし、繋がって情報交換したいよなぁ」</b>
　<b>「論文にあるベストな摂取カロリーとかエクセルでやるの面倒だし結局やらないよなぁ」</b>
という課題の解消ですね。

## 前提条件（学習期間）と開発期間は？
プログラミング学習を開始したのが2020年5月末。
当時はHTMLとかJavaとか、まぁ言語の名前だけは聞いたことあるという状態。

####・6月
仕事をしつつ主にProgateで勉強し、10種類以上のコースを各1周。
HTML&CSS,Python,Java,PHP,SQL,Git,Sass,Rubyあたり。JavaScripとRailsも途中まで。

####・7月
小さなプログラミングスクールに入校。(コロナの影響でほぼオンライン)
内容は
・PHP/Laravelの3ヶ月コース。
・テキストベースのカリキュラムでHTML、PHP、Laravelを学びつつ課題をこなしていく形。
・開発環境はAWSのCloud9。
・週に1回オンラインで1時間のメンタリング。
という感じ。

####・8月～10月
8月上旬にはカリキュラムを終了し、
オリジナルアプリの制作に向けて企画/設計やER図作成を開始。
8月中旬から実際の開発作業に着手。
9月末でスクールは退会。
10月にAWSの学習とデプロイ作業。
という流れです。

### 開発期間
開発期間としては、<b>働きながら&勉強しながらとはいえ3ヶ月程度費やしている</b>ことになりますね。
時間をすべて記録していたわけではないので何とも言えませんが、
まず可処分時間は平均しておおよそ<b>3時間/日程度</b>を確保。
テレビはコンセントを抜いてゲームやYoutube等は撤廃、食事や大好きな読書も最小限にしました。

ITパスや基本情報技術者、AWSや各種技術書などの勉強も行っていたので、その半分の1.5時間をアプリ開発に充てたと考えると3ヶ月でだいたい<b>150時間</b>は費やしていることになります。
(6月からの学習時間や資格勉強なども全てトータルすると<b>450時間ほどのプレイ時間</b>になりますね..）

そしてやはり感じたのは、調べ物やエラーと戦っている時間がほとんどで、
`実際にコードを書いてる時間は少ない`ということですね。。
よく言われることかもしれませんが。

## 企画/設計はどんな感じで行った？
・アイディア出し、ペルソナ設定
・リーンキャンバスの作成
・エレベータピッチ、ユーザーストーリーマッピング、MVPの設定
・ワイヤーフレームの作成(手書き)
・ER図の作成(手書き)
という手順で行いました。

収益化が主目的ではないのでリーンキャンバスは埋められる範囲で、という感じですね。(KPIなど省略)
今思うとこのフェーズでもう少しアプリケーションの<b>ロジックの部分の設計ができていればなぁ</b>とも思いますが、<b>「走りながら考える」</b>というのもまた正解でもあるので、何とも言えないですね。

## データベース設計(ER図)はどうなってる？
最初に手書きで簡単に作りつつも、開発しながら随時テーブルは更新/拡張していき、
結局はこのような形になりました。
中央のusersテーブルを中心に投稿や計算データといったテーブルと関連付いています。
<img alt="ER図" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675596/70016003-9103-dec3-5f2c-73519805db38.png" width=80%>



実装してみるとやはりテーブルの関連付けの部分が難しく、キー制約や正規化などDBの奥の深さや面白さを感じました。
そしてどうしてもやっているうちに開発前の構想とは変わっていくので、Migrationファイルがやや散らかってしまいました。。

## インフラ構成はどうなってる？？
すべてAWSで構成。主に使用したのはEC2、RDS、ELB、S3、Route53、ACMです。
<img alt="インフラ構成図" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675596/e566dd96-576a-d5f7-81a4-51c0714b5647.png" width=80%>

本来はWebサーバーやDBサーバーは冗長化させて、S3もCloud Frontで..という想いはあるのですが、あくまで学習用。`無料枠の中で`ということで断念しました。
ELBはロードバランサーというよりAmazon Certificate Managerで無料でhttps化(証明書発行)する目的で使用しています。(EC2インスタンスは1つで、ダミーのAZを設定)

またAWSを利用する上でルートユーザーはMFA(多要素認証)でログイン、IAMユーザーに最小限の権限を持たせて作業、アクセスキーは厳重に管理、といったセキュリティ面は留意しました。(少し痛い目にあったので..)

## アプリを制作する上で意識したことは？
### コードをコピペしない
まず、<b>「絶対にコードをコピペしない」</b>ということを意識(というか禁忌に)しました。
実際に効率を重視する場面ではわかりませんが、学習を目的としてアプリ開発している以上、ネットの記事などからそのままコピー＆ペーストして動いても何の意味もないと考えます。
もちろんVSCodeなどのスニペットは使いますが、やはり意味を考えながら手を動かしていくことが大事なんじゃないかなぁと思いますね。

### ひとりチーム開発
次に、<b>実務を想定した「ひとりチーム開発」</b>を意識しました。
スクール等でチームを組んで共同開発..というのがひとつの理想ではありますが、個人開発なので「どうやったら実務でスムーズにキャッチアップできるか？」ということを考え、
　<b>・Git/GitHubによるソース管理</b>
　<b>・作業ごとにissueを作成し、featureブランチを切って作業</b>
　<b>・こまめにコミットし、プルリクエスト。</b>
といった形で開発を進めました。

開発用にGitHubの新規アカウントを作成し、contributionsはこのようになりました。
いわゆる`草`というやつですね。これからも更新していきます。
<img alt="githubのcontributions" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675596/73257911-73c3-ee8e-3494-0eebc5870d3c.png" width=55%>

もちろん実務ではDockerでの開発環境、CI/CDパイプライン等いろいろと必要な事項があると思いますが「まずはアプリ自体を完成させなければ..」という想いから、このあたりの技術は転職活動〜入社の期間で少しずつ習得していこうと考えています。

### わかりやすいコードにする
個人開発ではありますが<b>「後から見た時にわかりやすいコード」</b>を意識しました。
現職(構造設計）でもドキュメントやメモを残すようにしていて、プログラミングにおいても意識してコメントは書いていたのですが、開発途中で<b>書籍「リーダブルコード(O'RELLY社)」</b>を読んで、リファクタリングを意識的に行うようになりました。
書籍の中では`「そもそも最小限のコメントで分かるような変数名やロジックにする」`というのが一番感銘を受けたポイントですね。。
変数やファイルの命名センスは大事。ロジックもコメントもセンスが大事。
(美しいコードとは？みたいなテーマで飲みながら語らえるようになりたい)

### インフラにAWSを使う
少し話が脱線しましたが..
他には<b>「インフラにAWSを使う」</b>というのも実務を意識した点です。
なぜAWSか？ については、
　<b>・教材でherokuにデプロイは経験していた</b>（あとは読み込み遅いとかドメイン名とか)
　<b>・インフラ設計や構築について実際に手を動かして学びたかったから</b>（分かってくるとインフラは楽しい)
　<b>・業務で最も使われているから</b>（AzureやGCPも気になりますが）
です。

## 苦労した点は？
これはもう、とにかくたくさんあるのですが、、
・エラーや不具合にハマったとき（ほぼ毎日）
・投稿した画像を自動で加工する機能のあれこれ（InterventionImageを使いましたが色々問題発生）
・Ajaxでの計算機能,いいね機能の実装と理解（ControllerとViewとJSの処理のロジックが難しかった..）
・Gitでコンフリクトが生じた時（コミット打ち消しを行ったことなどに起因..）
・AWSの概念理解とデプロイ作業（https化も意外と大変だった..）
・環境構築の問題いろいろ（Composerメモリ足りない→php.iniとswapで対処等）
などなど、多岐にわたります。

開発期間はほとんど独習だったので、
<b>「調べつつメンター契約して即時解決」というほうが良かったかも、、</b>
ただ、苦労はしたけど"勉強が辛い"という感じはしなかったですね。(たぶん学習レベルだからですが)

## 全体的な感想
まず<b>Webアプリを作ることは楽しい</b>ということ。
もちろん大変なことや覚えなければならないことは山ほどありますが、
　<b>・ロジックを考えてそれが実装できたとき</b>
　<b>・エラーやデプロイの問題が解決できたとき</b>
はガッツポーズしてしまうほどの達成感です。
また<b>日々自分が成長していくこと</b>にもやりがいを感じますし、
自分と同じ問題で<b>困っている人に教えてあげること</b>にも喜びを感じました。
実際にサービスを提供して誰かの課題を解決できたら最高かもしれないですね。
<br>
それと蛇足ですが..
自分の場合プログラミングスクールは通う必要はなかったかなぁと後から思いました。

もちろん「大金を払っているので後戻りできない」とか「カリキュラムが体系的になっている」とか「質問できる環境」というメリットはありますが、、
今はもっと安くて分かりやすい教材や動画もありますし、だいたい何でも調べられるので<b>「独学で充分できるかも..」</b>と後から感じています。

当時にもう少し情報の収集力があれば良かった..けど後からなら何でも言えますね。
googleで検索してもアフィリエイト記事にしかたどり着けないですし。

## 今後の課題など
・Docker,CI/CDなど、開発環境,テスト,自動デプロイあたりについて学ぶ
・ユーザー登録時にメール認証させたりセキュリティ面もきちんと考える
・PHPを生の言語としてもっと深く学ぶ
・インフラ、ネットワーク、Linuxの基本をしっかり学ぶ
・UI/UXをもう少し意識する

まぁ実際にサービスを運用するとなるとやるべきことはもっとあると思いますが、少しずつ着実に力をつけていきたいなと考えております。
<br>
以上、最後までご覧いただきありがとうございました。
「おつかれ!」「もっと頑張れよ!」と思ったらLGTMをポチッとしていただけたら嬉しいです。