見出し画像

【Go初学】パッケージ管理型API

こちらの記事で試しているパッケージ志向アーキテクチャをベースにどのようにAPIを開発してみたか所感を記述したい。

▼比較

リンクの通り、各API は internal/api/v1/<各APIパッケージ>の配置としている。

├── cmd
│   ├── go.mod
│   ├── go.sum
│   ├── main
│   └── main.go
├── internal
│   ├── api
│   │   └── v1
│   │       ├── user
│   │       │   ├── controller.go
│   │       │   ├── go.mod
│   │       │   ├── go.sum
│   │       │   ├── model.go
│   │       │   ├── repository_test.go
│   │       │   ├── repository.go
│   │       │   ├── route_test.go
│   │       │   ├── route.go
│   │       │   ├── seed_test.go
│   │       │   ├── service_test.go
│   │       │   ├── service.go
│   │       │   └── viewmodel.go

これはパッケージ志向の「パッケージの目的は、特定の問題ドメインに対する解決策を提供することです」を表している。つまりこのパッケージ内で特定のドメインの問題を解決する。
「Controllers」「Repositories」「Models」のようなディレクトリを作成して各APIの構造体ファイルがそれぞれで格納されているタイプをレイヤー志向として比較すると両者で以下のような点が異なる。

■ドメイン境界(横断の可否)
レイヤー志向は上位の階層が下位の階層にアクセスする構造のため、下位の別ドメインの領域へアクセスすることができるが、パッケージ志向は別パッケージとなり、循環参照になるためアクセスできない(片道は可能だがするべきでない)。
パッケージ志向のレイアウトは経験が無く、パッケージ管理の煩雑さ(小規模であれば尚更)などデメリットもあるが、RESTFul APIであれば特定のドメインにのみ関心があるはずなので構築できるのではと思い、実験の意味も込めてトライを行なってみた。
レイヤー志向は1画面で複数の要素が絡むWebアプリケーションのプロジェクトなどであれば横断的にアクセスしたい要求に叶い(注文画面では注文する商品の情報や注文それ自体の情報、また会員の情報など複合的に情報が必要になる)、パッケージ志向では難しいと思われる。

■スコープ(影響範囲の広さ)
上記の境界に絡む部分で、レイヤー志向の横断的なアクセスがある場合はより影響範囲が広くなる。利用される下位層の処理は、パッケージ志向の場合と比べて広く利用され、その領域の変更がもたらす影響も大きくなる。パッケージの形でかつ外部へ公開していない閉じた領域においては、影響範囲はその領域に収まることが保証される。
影響範囲を小さく出来るということは変更(処理方法、または処理の全体の置き換え)が容易であり、把握しなくてはいけない事柄が少なくて済むようになり、開発効率に影響する。

▼メリット/デメリット

■メリット
パッケージでカプセル化された閉じた領域にすることで不要な影響範囲や依存を考えなくてよくなり開発に集中しやすい。実際公開する必要があるのは、どのリクエスト(HTTPメソッドとURLの組)に対してどのハンドラーを呼び出すかだけになる。またディレクトリ名が既にリソースを表しているためファイル名が短くて済む。

■デメリット
各API全てパッケージのためパッケージ管理が煩雑になる。API追加の度に go.mod ファイルを作成し内部パッケージ参照のための replace を加え、利用する側も追加する必要がある。

▼あとがき

実験的なプロジェクトでファイル配置を変えては戻してみたり試行錯誤を行ってきた。一枚岩なフレームワークで中で何やっているか分からない使い方をするよりも、充実した標準ライブラリを必要に応じて組み合わせて形にするところがGoの面白いところなのではと感じている。試行錯誤を繰り返すこと自体遠回りなうえに正しい成果とならないこともあるが、手を動かしてあれこれ試してみるところからも学べるところは多い。今後も色々試して失敗していきたい。

この記事が気に入ったらサポートをしてみませんか?