Skip to content

Latest commit

 

History

History
150 lines (99 loc) · 4.26 KB

File metadata and controls

150 lines (99 loc) · 4.26 KB

クリーンアーキテクチャで REST API

クリーンアーキテクチャ(OOP:Object-Oriented Programming)

オブジェクト指向の概念は取り入れているものの、オブジェクト指向に限定されるアーキテクチャではない。

システムを以下のような層に分けて、依存関係を明確にし、変更に強いシステムを設計する方法

  • 中心(エンティティ層) ビジネスルールを明確にし、アプリケーションに依存しない

  • ユースケース層 アプリケーション固有のビジネスロジックを定義

  • インターフェースアダプタ層 外部システム(データベース、API)ブリッジ

  • フレームワーク層 フレームワーク、外部ライブラリを使った具体的な実装

クリーンアーキテクチャの基本原則

依存逆転の原則(DIP:Dependency Inversion Principle)を実現することが目的

オブジェクト指向の特徴

  • カプセル化
  • 継承
  • ポリモーフィズム:同じインターフェースを持つ異なる実装を切り替える仕組み

go のエトセトラ

go mod = Go Modules の省略であり、依存関係管理システムのこと

go mod init

go.mod の内容

  • モジュール名
  • Golang のバージョン
  • 依存関係

依存関係の整理

go mod tidy

docker command

webapp2 つのコンテナを起動:docker up -d

※コンテナは裏側で動いてるため、ターミナルでは動いて見えない ※-dがなくても dockerDesktop を開いていれば、立ち上がるが、ターミナルを一つ使うことになる。

コンテナ一覧:docker ps

type UserResponse struct {
	ID    uint   `json:"id" gorm:"primaryKey"`
	Email string `json: "email" gorm:"unique"`
	// 文字列がズレる。インデントチェックした方が良いかも
}

スクリーンショット 2025-01-01 11 20 58

GO_ENVの値がdevだったら load 関数が走り、ローカルで持ってる.envを見に行ってる。

func NewDB() *gorm.DB {
	// ここにDBの初期化処理を書く
	// 環境変数を読み込むための処理
	if os.Getenv("GO_ENV") == "dev" {
		err := godotenv.Load() // .envファイルを読み込む
		if err != nil {
			log.Fatal(err)
		}
	}
}

注意

docker も立ち上げてないと動かないからね。

go run migrate/migrate.goしたら、

pgAdmin で生成したテーブルを確認できる。

スクリーンショット 2025-01-01 11 20 58

golang の独特記法

短縮変数宣言

下の:=varの変数宣言はイコール

:= === var hoge string = fuga

method receiver

func (レシーバー名 レシーバー型) メソッド名(引数) 戻り値型 {
    // メソッドの処理
}

func (uu *userUsecase)

CRUD チェック

  • docker-compose 立ち上げ
  • go run migrate: 'GO_ENV=dev go run migrate/migrate.go'
  • echo run 'GO_ENV=dev go run main.go'

ログチェック

println()がログ出力

あとで調べよう

ポインタ

レシーバー

あんまり理解してないけど発生したエラー

echo-jwt ライブラリがプロジェクトに複数入ってしまっていて、 API がどのライブラリを参照すれば良いか迷子になってしまっていた。

v5 を消して、modしてたけど、復活しちゃってたが、動画と同じ v4.1.0 に変更したところ、req 通った。 chat gpt なかったら絶対わかんなかった。と思う

deleteだけできない。。。

func (tr *taskRepository) DeleteTask(userId uint, taskId uint) error {
	//! この書き方は、決まってる Delete(&構造体名{}) Delete(&model.Task{})
	result := tr.db.Where("id=? AND user_id=?", taskId, userId {/* ← ormのtaskIdとuserIdの順番間違えてた。入れ替えたら治った*/}).Delete(&model.Task{})
	if result.RowsAffected < 1 {
		return fmt.Errorf("object does not exist")
	}
	return nil
}