完全未経験が半年で個人サービスをリリースした話

## はじめに
この度、転職とスキル向上を目的に個人サービス([Football League](https://football-league-sports.com))をリリースしました。

ITに関する学習は約1年ほど、その内の半年でサービスの開発をしました！

まだまだ修正箇所はあるものの、ひとまず形にはなったのでサービスの使用技術や開発過程を共有したいと思います。

私自身、独学で学習してきたのでそういった方々にとって少しでも参考になれば幸いです。

## 自己紹介
商業高校卒(サッカー部⚽️)
25歳
青森住み🍏
職業はトマト農家です🍅

## どのようなサービスか
本サービスは、欧州5大リーグのサッカーの試合結果やチーム情報などを閲覧することができるWebサイトです。

ただ情報を閲覧できるだけでは面白みがないので、お気に入りのチームやリーグを追加することもできます。

### なぜ作ろうと思ったか
私自身、小学生の頃から社会人になった現在までサッカーをやっています。

サッカーだけではなく、スポーツをやっている人であればなにかしらの情報サイトやアプリは使ったことがあると思います。

しかし、意外と自分が興味のあるチームや試合などの情報に特化したサービスは少ないと感じました。膨大な情報からすぐに興味のある情報へ辿り着けるようなサービスがあったらいいなと思いました。

特に、世界で一番注目されている欧州5大リーグに特化したサービスがあまり見当たらなかったので、これは自分で作ってみようと思い開発に至りました。

## 主要な使用技術
**フロントエンド**

- [TypeScript](https://www.typescriptlang.org/) (5.1.6)
- [React](https://react.dev/) (18.2.0)
- [React Router Dom](https://reactrouter.com/en/main) (6.14.1)
- [Axios](https://github.com/axios/axios) (1.1.2)
- [React Hook Form](https://react-hook-form.com/) (7.45.4)
- [React Tooltip](https://github.com/ReactTooltip/react-tooltip) (5.18.0)
- [React Card Flip](https://www.npmjs.com/package/react-card-flip) (1.2.0)
- [Tailwind CSS](https://tailwindcss.com/) (3.3.2)
- [Material-UI](https://mui.com/) (5.14.6)

**バックエンド**

- [PHP](https://www.php.net/manual/ja/index.php)(8.0.2)
- [Laravel](https://laravel.com/)(9.19)
- [Laravel Sanctum](https://readouble.com/laravel/8.x/ja/sanctum.html)(3.0)
- [Laravel Fortify](https://readouble.com/laravel/8.x/ja/fortify.html)(1.17)
- [Socialite](https://readouble.com/laravel/8.x/ja/socialite.html)(5.9)
- [Guzzle](https://readouble.com/laravel/9.x/ja/http-client.html)(7.2)

**コンテナサービス**

- [Docker](https://www.docker.com/ja-jp/)

**バッチ** 

- [AWS Lambda](https://aws.amazon.com/jp/lambda/)
- [Python](https://www.python.org/) (3.11) - Lambdaランタイム

**ストレージ**

- [Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/) (Amazon S3)

## インフラどうする...
クラウド自体触ったこともなかったので理解するためにAWSの認定資格をいくつか取得しました。

今思えば本当に取得しておいて良かったと思います。そういえばあのサービスとこのサービスを組み合わせれば良かったんだよなみたいな感じで、アーキテクチャを構成する上で非常に役立ちました。

### 保有資格
| 資格名 | 取得月 |
| ---- | ---- |
| AWS Certified Cloud Practitioner (CLF-C01） | 2023年4月 |
| AWS Certified Solutions Architect Associate (SAA-C03） | 2023年4月 |
| AWS Certified SysOps Administrator Associate (SOA-C02） | 2023年4月 |
| AWS Certified Developer Associate (DVA-C02） | 2023年5月 |
| AWS Certified Solutions Architect Professional (SAP-C02) | 2023年12月 |
| AWS Certified DevOps Engineer Professional (DOP-C02) | 2023年12月 |
| AWS Certified Advanced Networking Specialty (ANS-C01) | 2024年1月 |

## インフラ構成図
色々と調べた上で最もベーシックな構成にしました。
本来冗長化することが望ましいがコスト面を考慮して最低限のリソースに抑えています。(RDS高すぎた)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/0679dbbe-e5f7-f5c1-9930-01a1355d0ea3.png)


### こだわりポイント
運用上、バッチでDBのデータを最新化する必要があるためバッチ処理を実装しています。

バッチの構成リソースはEventBridgeでデータ更新用のLambda実行をスケジューリングすることにしました。
(ここに至るまでもそもそもバッチとは、、みたいなところから調べました)

LambdaはRDSと通信が必要なので同じプライベートサブネットに置いています。

しかし、これだとLambdaがインターネットと通信ができなくなってしまうので、パブリックサブネットにNAT gatewayを配置してインターネット通信をできるようにしています。

バッチのログはCloudWatch Logsで収集しているので、今後はLambda,SNSなどを使用してSlackへの通知なども実装してみたい


### その他
#### 環境変数の管理
Lambdaで使用する環境変数はSSMのParameter Storeで管理しています。
APIキーやパスワードなどの秘匿情報に関してはKMSを使用してシークレットとして管理しています。

#### メンテナンスページ
EC2でメンテナンス時には、ALBでメンテナンスページを表示するようにしています。

CloudFrontやS3を使用しなくても固定レスポンスを返せるのはかなり便利だと思います。

ただ何かと制限もあるので、カスタマイズするなら他の方法が良さそう？

## ざっくりと画面紹介
**ログイン画面**

![スクリーンショット 2024-01-09 19.18.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/8f4995e6-029b-0d79-ca36-88883ebe2f94.png)

---

**入力時バリデーション**

![スクリーンショット 2024-01-09 20.09.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/903c10fe-9321-5e50-4979-c06bb8c91804.png)

---

**新規登録画面**

![スクリーンショット 2024-01-09 19.50.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/50230bdf-3fcd-c878-034b-161e94b2dd16.png)

---

**登録後の認証確認通知**

![スクリーンショット 2024-01-09 20.10.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/a839098c-6906-ce3a-6305-87c85cb5b53a.png)

---

**ホーム画面**

![スクリーンショット 2024-01-09 19.22.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/580d132c-f7d8-9789-37ce-cf2c35efc194.png)

---

**試合詳細画面**

試合の統計情報をゲージバーを使用して視覚的にわかりやすくしました。
![statistics.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/18de94f5-6201-2e72-af5b-0a85b733c419.gif)


各チームのフォーメーションを見やすく表示し、カーソルを合わせると選手の写真を確認することができます。
![formations.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/884be91b-c4d7-3acc-c5a8-15e320eb6c86.gif)


---

**順位表画面**

![スクリーンショット 2024-01-09 19.28.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/da3cc4db-debd-e27e-778a-1ef34d39cfbf.png)

---

**お気に入り追加**

検索時にスケルトンローディングを実装しユーザーの待ち時間を直感的に短くしています。
![favorites.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/b9998a42-d1d8-eba5-1e29-3f76b0536dac.gif)

---

**お気に入りはサイドバーから確認可能**

![スクリーンショット 2024-01-09 19.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/e6474019-ec58-b1fa-3b07-84a1451db417.png)

---

**チーム詳細画面**

![スクリーンショット 2024-01-09 19.44.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/9edca9a8-692c-92b0-9abb-5a3c21218cea.png)

---

**リーグ詳細画面**

![スクリーンショット 2024-01-09 19.45.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/13c1666f-2d91-fc4b-51b2-c11c2b931620.png)

---

**選手詳細画面**

![スクリーンショット 2024-01-09 19.48.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/e63a3c2d-6af8-a1cc-3b72-046bc23873a2.png)

---

## 設計の大切さを知る
作るものが具体的に決まり、プロジェクトに取り組む前に設計を行おうと思いました。しかし、設計といっても、最初の一歩を踏み出すのに苦戦しました。

最初はある程度、論理設計や画面設計、API設計などをして開発に取り掛かりましたが、設計がガバガバだったせいで何度も手戻りが発生し開発どころではなくなってしまいました。

コードを書きながらその都度修正していけばなんとかなるだろうみたいな感じで設計を軽く考えていたのが原因。

### 設計の重要性
この経験から、設計の重要性を痛感しました。設計はプロジェクトの土台であり、しっかりとした基盤があればコードの修正や変更にも柔軟に対応できます。しかし、ガバガバな設計ではプロジェクトが進行するにつれて構造が崩れ、修正が難しくなることがわかりました。

### 詳細な検討が必要
単なるアイデアや概念だけでなく、具体的な機能や要件、データベースの設計など、細部にわたって検討する必要があります。APIのエンドポイントやデータの流れ、UIなど、開発に入るだけでも考えなければいけないことが沢山あることがわかりました。

### 設計で使用したツール
[Google スプレッドシート](https://www.google.com/intl/ja_jp/sheets/about/)
[draw.io](https://www.drawio.com/) - インフラの構成図やER図の作成に使用
[Notion](https://www.notion.so/ja-jp) - 簡単なメモなど

## ER図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/23d196bb-f566-ac15-8b99-8143f7b72dc5.png)



## 実装機能
- 認証系
    - ログイン/Googleログイン
    - ログアウト
    - 新規登録
    - 認証メール
    - パスワードリセット
    - パスワード変更
    - アカウント削除
- お気に入り機能
    - チームのお気に入り追加
    - リーグのお気に入り追加
    - お気に入りから削除
    - 検索
    - ページネーション
    - お問い合わせ

## 開発で使用したツール
### [Postman](https://www.postman.com/)
本サービスはSPAなのでLaravelはAPI化して使用しています。

APIのレスポンスの確認などをブラウザでいちいち行うのは面倒ですし、さっと確認したい時があります。そこで、**Postman**というAPI開発ツールを使用しました。

**Postman**はAPI開発のために使用されるツールで、APIの任意のエンドポイントにHTTPリクエストを送り、レスポンスを受信することができます。

API単体で動作を確認できるので、かなり便利。
(Laravel Sanctumを使用しているのでCSRFトークンを初期化するコードを書かなければいけなかったのですが、少し苦戦)

### [Sequel Ace](https://sequel-ace.com/)
データベース管理ツールは何種類かあるのですが、有名な**Sequel Ace**を使用しました。

Mac用MySQL GUIクライアントアプリで簡単にDBの確認や操作を行うことができます。

## 感想
ここまで読んでいただきありがとうございます。
フロントエンドやバックエンド、インフラの技術的な内容は別途記事にしたいと思います。

今回、人生で初めて個人サービスを開発、リリースすることができました。
これまでは、ToDoアプリなどを開発したことはありますが、今回は設計からインフラまでの一連の流れを経験できたのは非常に充実感がありました。

まだ改善点などやるべきことが残っていますが、ひとまず形になったことが嬉しいです。

私自身、最初は全くの未経験で、何から手をつけて良いのか戸惑うこともありました。開発を進めていく中で、少しずつですが出来ることも多くなり、開発のペースも上がっていった印象です。

AWSのインフラをコードで管理したり、CI/CDの実装などやりたいことは沢山あるので、これからも技術力の向上に向けて頑張りたいと思います。