Golang
の基本的な知識を習得するために開発している Todo アプリになります。
基礎的なところから理解を図るために極力、フレームワークを利用せずに開発に努めております。
また合わせて、React+TypeScript+Redux
の組み合わせでアプリを作成することも目標としており、こちらも最低限のパッケージで開発を進めております。
アプリのコンセプトとしては以下のサイトのタスク管理をアプリケーション化したらというコンセプトのもと機能や要件を考えて開発を進めております。
参考サイト
作成したポートフォリオサイト
平日の 9:30~20:00 の間で起動しており、それ以外の時間帯はサービスを落としております。
22/07/15 現在はサービスを終了しております
Client(React)
側においてRedux/TypeScript
において状態管理
React
を用いた開発における必ず上がる課題として状態管理があるかと思います。現在、便利なHooks
なども出てきてはおりますが、現場ではやはりまだ使用率の高く知識を活かせる可能性が高いRedux
を用いて状態管理をおこなっております。一方、Redux+TypeScript
を用いる場合によく用いられるtypescript-fsa
やRedux-Toolkit
は使用せずに型指定した状態(state
)の受け渡しの流れをより意識できるのではないかと考え素のTypeScript
でRedux
の構築を図りました。
- API(golang)を
Clean Architecture
にて設計
以前に Ruby on Rails
にて作成したポートフォリオは Rails
の設計である MVC
に準じてアプリケーションを作成しました。
今回は別の視点からアプリ開発の知識を得ることを目標に設計にClean Architecture
を採用しました。保守性などの観点からMVC
以上に各担当役割を細かく分けている設計思想なので、コーディングの際は常にファイルの役割を考えつつ多少コードの記載量が増えても役割ごとにファイル分割を意識しました。
- データ整合性を維持するデータベース処理
Transaction
を、上位レイアのアプリケーション層で実行できるようにinterface
を用いたダックタイピングにて実現
Todo
をタグ分類するために、モデルとしてTodo
,Tag
中間テーブルとしてTodo_Tag_Relations
を作成。Todo
とTodo_Tag_Relations
を保存する際に、どちらか一方が保存処理に失敗した場合、Rollback
をするように設計しました。ポイントとして、transaction
にまつわるデータベース操作はClean Architecture
においてinterfaces/database
層が制御することになりますが、アプリにおけるデータの保存や廃棄の判断はより上位レイアのusecase/interactor
(アプリケーション)層が関心をもつ必要があります。一方、上位レイア(アプリケーション層)は下位レイア(interfaces/database
)に依存することはClean Architecture
においては設計思想に沿いません。そのため、DIP(依存関係逆転の原則)の考えのもとinterface
を用いて、いわゆるダックタイピングによりアプリケーション層にてTransaction
操作を実現しました。
- API(golang)側の
Mock
を利用したテストコード
上述の通り、API 側の設計として、Clean Architecture
を採用しており各種役割ごとに階層化されており、効率的にテストするために初めてgoMock
を採用しました。
とくにアプリケーションロジックの役割をになっている api/usecase/interactor
をテストする際に、通信やデータベース処理おいて発生したエラーなどアプリケーションロジックに関係ないエラーを排除できるような設計にできました。
- インフラ管理を自動化
インフラとしてAWS
を利用しておりますが、構築はTerraform
を利用しており、インフラ構築やアプリケーションの起動をTerraform
コマンドで実行しております。
また、GitHub Action
を利用しており、アプリケーションの変更、修正がGitHub
にプッシュされたタイミングにテストが自動的に実行され、main
ブランチにマージされたタイミングでAWS
へ自動デプロイ。
開発の効率性、開発体験の向上を実現しました。
バックエンド
- Golang(Go Modules)
- Nginx
- MySQL
フロントエンド
- React(create-react-app/Material-ui/Redux)
- TypeScript
- HTML/CSS
Golang 主要パッケージ
- go-playground/validator
- gorilla/mux
- gorilla/sessions
- joho/godotenv
- rs/cors
- ini.v1
- stretchr/testify
- .air(Golang のホットリロード)
- deleve(Golang におけるデバッグ)
インフラ関連
- docker(開発環境+本番環境構築)
- GitHub(バージョン管理)
- GitHub Actions (CI/CD)
- Terraform(IaC)
- AWS
- VPC
- Internet Gateway
- ACM
- ALB
- Fargate
- ECR
デザインツール
- Figma
*事前に Figma によりサイトデザインを構築してから View にまつわるデザイン構築に取り掛かりました。また、ロゴ等に関しても Figma を用いて作成しました。
- 前回、
Ruby on Rails
でアプリを開発しており、次は静的型付け言語でフレームワーク無しの開発を考えていた Rails のポートフォリオ - コードがシンプルで静的型付け言語においては学習難易度が低い
- アプリを作成するためのライブラリが豊富
- 近年の言語としての勢い
- コンポーネント分割に重きをおくライブラリで、ある程度の分割が出来ていれば可読性が上がるのと同時にメンテナンス性が上がるため
TypeScript
を併用することで型によるさらなる安全性の向上Vue
との比較で、より深くJavaScript
の理解が必要なReact
にキャリア初期から触れることで自己成長につながるのではないかと考えたため
- 開発環境と本番環境での環境差異の解消
- ローカルでも仮想本番環境を実現できてデプロイ作業の負担軽減
- 近年、コンテナデプロイが増加している傾向だったので、知見を得るために挑戦
- インフラをコード化することで、インフラ理解がより深まりまた学習記録として残せる
- 今回の Fargate/RDS と料金が高額なリソースを仕様しており、即時に立ち上げ/破壊が可能なので節約につながる
- CI において以前作成したポートフォリオにおいては Circle CI を利用していたが、すべて GitHub 上で完結できる点に GitHubAction の魅力を感じた
- コンテナを用いたデプロイはデプロイ作業に時間がかかるために、GitHub Actions の CD 機能を用いて自動化を図り開発体験の向上を目指した
api(golang)/Clean Architecture を採用
以下の理由で採用
- 再利用性の高い設計になり生産性が向上する
- コードの可読性が上がり、メンテナンスが容易になる
- 変化に強い設計になる
client(react)/Atomic Design を採用
以下の理由で採用
- コードの再利用性が高いの効率的に開発が可能
- メンテナンスが容易になる
User
- 新規登録
- ログイン
- ログアウト
*session と cookie を利用することでにログイン状態の確認
Todo
- 新規投稿
- 一覧表示
- 詳細表示
- 編集
- 削除
- 完了/未完了切り替え
- タグ分類
- タグ検索
- 重要度で分類
- 緊急度で分類
- 重要度、緊急度で検索
TaskCard
- 新規投稿
- 一覧表示
- 詳細表示
- 編集
- 削除
- 完了/未完了切り替え
その他
画像投稿/保存/配信
Toast による通知機能
Todo が 5 以上投稿されるとページネーションにより、データの一部取得
コマンドを実行することでテストデータを自動作成
一部、ファイルに対してテストコードを作成
- クローン
git clone git@github.com:kory-jp/react_golang_mux.git
- ルートディレクトリへ移動
cd golang_react_mux
- 環境変数設定
React 側
touch client/client-app/.env
client/client-app/.env へキー(環境変数)を入力
REACT_APP_API_URL="http://localhost:8000/api/"
golang 側
touch api/env/development.env
api/env/development.env へキー(環境変数)を入力
API_PORT = 8000
LOG_FILE = apiapp.log
DRIVER = mysql
USER_NAME = root
PASSWORD = root
HOST = mysql_container
DB_PORT = 3306
DB_NAME = react_golang_mux
ALLOWED_ORIGINS = http://localhost:8080
ALLOWED_METHODS = "POST GET PUT DELETE"
ALLOWED_HEADERS = "Origin Accept Content-Type X-Requested-With Access-Control-Allow-Origin"
SESSION_KEY = sample-session-key
AWS_BUCKET = development
AWS_ACCESS_KEY_ID = development
AWS_SECRET_ACCESS_KEY = development
AWS_REGION = sample-region
- docker 起動
docker-compose build
docker-compose up -d
- サイトアクセス
- コンテナログイン
docker exec -it go_container /bin/sh
docker exec -it react_container /bin/sh
docker exec -it mysql_container /bin/sh
docker exec -it go_container /bin/sh
go run infrastructure/seeds/development/seeder.go
テストユーザーによるログイン
メールアドレス:
sam@exm.com
パスワード
password
golang のログを確認
docker logs go_container
MySQL のクエリを確認
/mysql/lgos/mysqld.log
- 実装したテストコード
api/interfaces/controllers/users/user_controller_test.go
api/interfaces/controllers/sessions/session_controller_test.go
api/interfaces/controllers/todos/todo_controller_test.go
api/usecase/user/user_interactor_test.go
api/usecase/session/session_interactor_test.go
api/usecase/todo/todo_interactor_test.go
- テストコード実行
cd api
sh test.sh
- 成功した場合
$sh test.sh
TEST START
TEST USECASE USERS OK
TEST USECASE TODOS OK
TEST USECASE SESSIONS OK
TEST USECASE TASK_CARDS OK
TEST CONTROLLER USERS OK
TEST CONTROLLER TODOS OK
TEST CONTROLLER SESSIONS OK
TEST CONTROLLER TASK_CARDS OK
TEST ALL COMPLETED
- 失敗した場合
エラーログの詳細が表示
以下のサイトを参考にデザイン