自分のおすすめの曲を紹介したい！！曲の紹介ができるアプリを作成しました。

# はじめに

はじめまして:raised_hands:
今回、曲を選曲できるアプリ「曲選曲」を制作しました！

曲を自由に選んで、投稿することができます。曲の幅を広げたい。未知なる曲を紹介されたい。みんなが気づいていない曲を紹介したい。そんな人におすすめです！

![スクリーンショット 2023-07-01 122721](https://github.com/ari5008/dev_frontend/assets/127650560/0b69d525-a62e-453d-97cf-1f8685f032f8)

## 作成した人
私は、現在大学4年生です。大学は文系でプログラミングに全く興味がありませんでした。
プログラミングに興味を持ったきっかけは、パソコン一台でアプリが制作できるという点に強く関心を抱きました。その後すぐにprogateからはじめたのですが、これは面白いと思い、独学で学習を続けてきました。現在までgo、reactと順に触ってきました。今では個人制作でアプリまで作れるようになったので、ぜひ見ていってほしいです！


## 目次は以下のとおりです
[1. 作成したアプリについて](#1-作成したアプリについて)
[2. 使用した技術](#2-使用した技術)
[3. 作成において考えたことについて](#3-作成において考えたことについて)
[4. 学習について](#4-学習について)
[5. 今後の課題](#5-今後の課題)

 

# 1. 作成したアプリについて

**自分の好きな曲を紹介し合えるWebアプリになります。**

### ▼サービスURL

 **「  [曲選曲](https://dev-frontend-ten.vercel.app)  」**

**testアカウント**
email　　　test@test.com
password　 password


### ▼GitHub URL
 **[フロントエンド(react)](https://github.com/ari5008/dev_frontend)**

 **[バックエンド(go)](https://github.com/ari5008/dev_backend)**



## アプリ概要

制作しようと思ったきかっけになるのですが、

暇な時間があれば、曲を聞く

　　　　**↓**
自分の好きな曲ばかり聴く

　　　　**↓**　　　
新しい曲を探すのが億劫になって、いつも同じ曲を聴く

　　　　**↓**
だんだん飽きてくる


このループを抜け出すために直感的に分かりやすく、誰でも簡単に曲を紹介できるアプリを制作してみようと思いました。
レイアウトは、選んだ曲が目につきやすい設計にしました。



## アプリの特徴

### (1) 主要な機能
#### 閲覧機能
- 曲を閲覧できます
    - タブから曲の並び順を変えることができます
    - 投稿者が確認できます
- コメントを閲覧したり、いいねを押すことができます ※修正中です


![ezgif com-video-to-gif (3)](https://github.com/ari5008/dev_frontend/assets/127650560/0aed9296-6af4-42a2-8290-f3de71a3db5f)

#### 曲選択機能
- 曲名を検索して、選択できます
    - 曲名を選択すると自動でアーティスト名とジャケットが選択されます
- ジャンルが選択できます
- コメントを残すことができます

![ezgif com-video-to-gif (2)](https://github.com/ari5008/dev_frontend/assets/127650560/37871675-910d-4dbf-accd-b57dd55c0c50)

### (2) ユーザー機能 
- ログイン機能 (アカウント登録なしでも曲の閲覧は可能です)
- ログアウト機能
- Myアカウント画面
    - ユーザー名とアイコンが変更できます
    - 過去の投稿が閲覧可能です
    - 曲の削除が行えます

![ezgif com-video-to-gif (4)](https://github.com/ari5008/dev_frontend/assets/127650560/70141571-24a8-414d-b514-707aa26860eb)


# 2. 使用した技術
### フロントエンド

- HTML 
- CSS
- react 18.2.0
- react-query 3.39.3
- react-router-dom 6.10.0
- chakra-ui 2.7.0
- react-data-table-component 7.5.3
- zustand 4.3.8
- vite 4.3.5

Reactを選定した理由は、柔軟に再利用やカスタマイズができるところに魅力を感じました。ReactとVueは迷ったのですが、関数型プログラミングに慣れていたので、Reactを選びました。また、非同期データの取得を簡単に行うためにreact-query、自然な階層構造を作成するためにreact-router-domを使用しました。

### バックエンド
- go　1.18
- echo 4.10.2
- postgres 1.5.0
- gorm 1.25.0
- golang-jwt 4.5.0
- echo-jwt 4.1.0
- go-ozzo 4.3.0

goを選定した理由は、型定義があって、書きやすく、これから需要があると聞いたので、試しに触ってみようと始めました。比較的、簡単に書けてパフォーマンスが良いところが魅力なのかなと思いました。その分、情報が少ないことがネックだと感じました。echoとgormを選んだ理由は、前回フレームワークをほどんど使わずに簡単なアプリを制作したので、今回はより楽をしたいと思い、使いました。簡単に実装できて、感動しました。

### その他
- VSCode
- Git 
- GitHub
- Docker （開発環境）
- docker-compose （開発環境）
- Dbever (開発環境)
- Postmann (開発環境)
- render
- vercel

開発環境で、postgresを起動するためにDockerとdocker-composeを使用しました。
DBの確認にdbever、backendの認証の確認にPostmanを使用しました。
本番環境にフロントエンドをvercel、バックエンドをrenderを使用しました。

### DB設計

#### ER図
![スクリーンショット 2023-07-10 172255](https://github.com/ari5008/dev_frontend/assets/127650560/283440f5-9343-460e-9ea4-b2fa3fe09f9d)

制作してから気づいたのですが、foreign keyを設定していませんでした。テーブルごとに線が引かれない簡素なER図になってしまいました。後日、修正したいと思います。

#### テーブル

##### users table
|     カラム名      |        属性         |      役割      |
| :---------------: | :-----------------: | :------------: |
|        id         |   整数/ nullではない|  ユーザー ID   |
|       email       |       文字列        | メールアドレス |
|     password      |       文字列        |   パスワード   |
|    created_at     |     日付と時刻      |    作成日時    |
|    updated_at     |     日付と時刻      |    更新日時    |

##### accounts table
|  カラム名  |       属性         |         役割          |
| :--------: | :--------------:  | :-------------------: |
|    id      |  整数/nullではない |  　　アカウント ID    |
| user_name  |　    文字列     　 |     ユーザーの名前    |
| image_url  |      文字列        |     アイコンImage     |
| user_id    |       整数         |     ユーザーの ID     |
| created_at |    日付と時刻      |       作成日時        |
| updated_at |    日付と時刻      |       更新日時        |

##### tracks table
|  カラム名    |    属性    |          役割        |
| :--------:   | :--------: | :------------------: |
|     id       | 整数/nullではない|   曲情報のID   |
|    title     |      文字列      |       曲名     |
| artist_name  |      文字列      | アーティスト名 |
| jacket_image |      文字列      |  曲のジャケット|
|    genre     |      文字列      |  曲のジャンル  |
|   comment    |      文字列      |  曲のコメント  |
|    likes     |       整数       |    いいね数    |
|  account_id  | 整数/nullではない| アカウントのID |
|  created_at  |    日付と時刻    |    作成日時    |
|  updated_at  |    日付と時刻    |    更新日時    |

##### like_flags table
|  カラム名   |    属性    |               役割       |
| :---------: | :--------: | :----------------------: |
|     id      | 整数/nullではない |   いいねのflagId  |
|  account_id |        整数       |    アカウントID   |
|  track_id   |        整数       |    曲情報のID     |
|    liked    |       真偽値      |   いいねのflag    |
| created_at  |     日付と時刻    |    作成日時       |
| updated_at  |    日付と時刻     |    更新日時       |





# 3. 作成において考えたことについて

## Reactの設計・レイアウトで意識したこと

### (1) シンプルで快適なUI/UX
不必要な機能を排除し、背景色や画面の配置などごちゃつきがないよう意識しました。そうすることで一目で状況が分かりやすいレイアウトができたと思います。
また、Chakra UIを用いて、エラーメッセージ、リロード、アニメーションなど、ユーザーにすぐに状況が伝わりやすい設計を心掛けました。

### (2) AtomicDesignを採用

:::note info
AtomicDesignとは
アトミックデザインは、UIの構成要素を5つのコンポーネントに分解し、順番に設計していく手法です。小さな要素から順番に組み合わせて、より大きなコンポーネントを作ることで、WebサイトのUIが完成します。
:::

AtomicDesignは、小さなコンポーネント単位から5種類に分類するため、再利用性が高く、管理のしやすいコードが書けます。そのため、コンポーネントの種類によって、どこに格納されているのか一目で分かるため、それぞれのパーツにおける機能や目的を理解しやすい設計ができたと思います。

こちらの記事が参考になると思います。
https://qiita.com/Kazuhiro_Mimaki/items/3d9a8594064aab5119da


## Goの設計で意識したこと

### (1) クリーンアーキテクチャを採用
クリーンアーキテクチャを採用した理由は、変更に強いアプリケーションを作り、依存性を排除したいと考えたからです。
具体的な説明をすると、階層をrepository、usecase、controllerに分けます。repositoryは、データベースと内部でやりとりする層になり、sql文(select文、insert文など)が記述されています。また、repositoryには、interfaceが定義されていて、このinterfaceが外部とのやりとりを行っています。次にusecaseは、さきほど定義したrepositoryのinterfaceと内部にやりとりし、データベースで取得した値を返す関数が定義されています。同じようにusecaseにもinterfaceが定義されていて、外部とのやりとりを行います。最後にcontrollerは、さきほど定義したusecaseのinterfaceと内部にやりとりし、rooterに設定する関数を定義します。同じようにcontrollerにもinterfaceが定義されていて、rooterはcontrollerのinterfaceを利用します。

**それぞれの階層ではinterfaceとやりとりを行うため、内部にある値を変更しても外部に影響がない点、また、一方方向にアクセスするため管理しやすい点が魅力だと感じました。**

こちらに記事が参考になると思います。
https://qiita.com/nrslib/items/a5f902c4defc83bd46b8

### (2) spotify APIを利用　
spotify APIを使用して、曲一覧を取得しました。Client Credentialsを利用することでAccess Tokenを取得し、spotifyのAPIとやりとりが可能になります。公式ドキュメントによると曲名やジャケット、アルバムなどの情報を簡単に取得できるのでおすすめです。音楽のアプリを制作したい人はぜひ使ってほしいと思いました。　

Client Credentialsの流れ☟
![スクリーンショット 2023-07-16 172154](https://github.com/ari5008/dev_frontend/assets/127650560/46bfb979-a5c2-4b2e-9e92-3f1e0fe9e00b)

## その他、制作時に意識したこと

### (1) それぞれの認証について
最初の設計時において、frontendとbackendの両方の認証を確認せず、情報を渡していました。そのため、開発画面で確認したとき、必ずエラーが起きて、どこでエラーが起きているのか判断することに大変苦労しました。その反省をもとにそれぞれの機能を小さく分けて、一つ一つ確認することを心掛けました。

例えば、ログイン機能であれば、Reactでログイン機能のレイアウトを作成し、goで認証を作成します。Reactでは開発者ツールで確認し、goではpostmanで確認します。postmanの確認が終えるとDBの認証が上手くいくかDbeverで確認し、それぞれの認証が上手くいくことを判別します。それぞれの認証が上手くいった場合は、backendで認証されたデータをfrontendに渡し、最終的な確認をします。そうすることでエラーが起きたときの判断が比較定容易になりました。同じように閲覧画面やアカウント画面などでも一つ一つのページや部品をfrontend、backendeで確認した後に繋ぎ合わせることで、確認のための時間はかかりますが、状況を把握しやすい開発ができたと思います。


### (2) githubの利用について

今後、実務経験を積む上でコミットの履歴を残したり、状況を把握しやすくすることは大事だと考えました。そのために意識したことが3点あります。

#### ① ブランチを切る
main、dev、featureのブランチを分けて開発しました。featureで開発し、devにmeargeして、プルリクを行います。開発は一人で行ったので、mainに対しfetchは行いませんでしたが、実務経験を積む時には、ローカルリポジトリのコードを最新の状態に保ちながら開発していきたいです。


#### ② issueとmilestoneを登録し、projectにまとめる
issueに機能追加を登録し、完了したらcloseする手順を取りました。また、milestoneでissueをまとめ、作成日時の期限と完了割合を見るために使用しました。さらにissueとmilestone、label、statusなどをprojectにまとめることで、表の形式で閲覧でき、全体の流れを把握しやすくできたと思います。

Reactのprojectになります☟
![スクリーンショット 2023-07-16 192906](https://github.com/ari5008/dev_frontend/assets/127650560/94a03b38-aa1d-46ff-af76-a5f0d2cd75c0)

#### ③ コミットメッセージの体裁を整える

コミットメッセージは[こちらに記事](https://qiita.com/konatsu_p/items/dfe199ebe3a7d2010b3e)を参考にしました。具体的にPrefixとコミット理由を書き、issueがある場合は、issue番号を書きます。そうすることで、コミットの理由が把握しやすくなったり、issue番号からコミットの履歴が追いやすくなるのがメリットだと感じました。

Goのコミットメッセージの例になります☟
![スクリーンショット 2023-07-16 195138](https://github.com/ari5008/dev_frontend/assets/127650560/e8f61dd3-c2a5-41ab-be96-ea565b9d6e0e)

# 4. 学習について

制作時間は、約300時間になります。期間にすると3か月ほどになります。就活を後回しにして、ポートフォリオを作ることに専念したので、気持ち的には焦りながら制作することになりました。結果的に、期限を設定し、限られた時間で取り組んだため、メリハリをもって学習できたと思います。

学習に関しては、約1年ほど独学で学びました。学習に関して、遠回りしたことが多くあったので、どうすればよかったのかアドバイスできればと思います。
 
- インプットをできるだけ早く終わらせ、アウトプットすることをおすすめします。私は、progateやudemyを何周もして、基礎を固めることを優先してしまいました。それよりもインプットで得た知識を使って何か制作物を作る方が、実践的なスキルが身につくと感じました。また、就活でもポートフォリオはあった方がエンジニアになりたいという説得力になると思うので、期限を設定して早く制作することをおすすめします。

- 制作時は、公式ドキュメントを参考にしました。エラーの内容や新しい機能を追加するときに正確な情報が手に入るので、困ったときには必ず見るべきだと感じました。

- ずっと考えてもエラーが解消できない場合は、睡眠をとって再度取り組むことで、頭がすっきりしてひらめくことがありました。しっかり睡眠をとることは大切だと感じました。

# 5. 今後の課題

### (1) 新たな機能作成について
アプリの機能として、曲の閲覧方法が少ないと感じました。そのために、曲をジャンルで分けたり、ユーザーが選んだ過去の曲を閲覧できるようにしたり、複数選ばれた曲を強調するような仕組みを今後追加していきたいと考えています。

### (2) インフラについて
今回は、手軽にデプロイしたいと考えたので、無料枠があったvercel(フロントエンド)とrender(バックエンド)を使ってデプロイしました。次回からは、ドメインとサーバーを契約し、一から構築していきたいと考えています。そのために、OS、Webサーバー、セキュリティー対策などインフラの基礎を抑えていきたいです。

### (3) コメント、テストコードについて
完成を第一に考えたため、ソースコードにコメントをほどんど残すことができませんでした。今後は、誰が見ても分かりやすく、機能の意図をはっきりさせるようなコメントを書いていきたいです。また、テストコードも同様に書けなかったので、今後追加していきたいです。

# さいごに
制作を終えて、プログラミングの学習に終わりはないと感じました。一つ一つ学習を重ねて、土台を築けるように毎日なにかしらのインプットとアウトプットをしていきたいと思いました。

今回記事を執筆するにあたり、こちらの記事が大変参考になりました。
- [【個人開発】駆け出しエンジニアのポートフォリオ作りを手助けするサービスを作りました](https://qiita.com/yusuke_blog1026/items/c68c45790a977cbd0715)
- [【個人開発】京都観光できっと大活躍！🍵京都の抹茶スイーツ店と神社仏閣のどちらも検索できるサービスを作った話。⛩【Rails7】](https://qiita.com/hiiragi_en17/items/721174747da020cd84f5)
- [【🔰独学】完全未経験から独学でポートフォリオ「だてまき」を開発しました【Laravel / Docker / AWS / CircleCI】](https://qiita.com/yuyamh/items/1f5c8b2e32420589dc41)

ご閲覧いただきありがとうございました！