Kiri ライブラリで、ネットワークリクエストの新しいやり方を試しています。
Kiri は Moya にインスパイアされたネットワーク抽象化レイヤーです。Moya のアーキテクチャにとても感銘を受けたので、そこから最大限学ぶために、コピー&ペーストではなく、同じアーキテクチャを自分の手でなぞって書いてみることにしました。:D
クライアントライブラリは 3 つの部分に分解して考える必要があります。
Request
通常、ネットワークリクエストは毎回組み立てなければなりません。
一方 Kiri では、ネットワークの設定を class や enum のような形で 1 か所にまとめて記述します。
そして、その class や enum は RequestContainer プロトコルに準拠している必要があります。
サンプルコードは次のようになります。
enum TestAPIRequest {
case getitems
case postitem
case updateitem
case deleteitem
}
enum TestAPIRequest: RequestContainer {
var baseURL: URL {
return URL(string: "https://www.example.com/api/v1")!
}
var path: String {
switch self {
case .getitems:
return "/getitems"
.....
}
}
....
}
これは API クライアントの設計という観点で優れています。
クライアントモジュールを作り始める前に、全体の構造をひと目で把握できます。
また、定数文字列をすべてのクラスに渡す必要もありません。Kiri は baseURL のような共通部分を持てるので、そうしたものをメソッドに切り出してラップしていけば、アプリ内の重複コードを避けられます。
ただし、API ごとにエンドポイントが異なるといった場合は、そう簡単にはいきません。そのようなケースでは、API ごとに別々のクラスを作りたくなるでしょう。それも理にかなっています。(残念ながら)そうした API に出会ってしまったら、代わりに APIKit を検討するのがよいと思います。APIKit はもともと API ごとにクラスを分ける設計になっており、レスポンスについても Kiri や Moya よりジェネリックなアプローチを取っています。
Networking
iOS には URLSession という独自のネットワーククラスがあります。しかし、今さら URLSession をラップする意味はありません。私たちには Alamofire があります。
Alamofire はリクエストとレスポンスを自動的にバリデーションし、JSON も返してくれます。とはいえ、ネットワークライブラリは複数のレスポンスフォーマットをサポートすべきなので、私はレスポンスを Data のまま保持するほうが好みです。
Kiri はネットワークリクエストに Alamofire を利用し、リクエストの構築を Alamofire に委譲しています。
ほとんどのケースで Alamofire はとてもうまく機能しますが、パラメータを自分で組み立てたいなど、よりプリミティブなネットワーク処理が必要な場合には向かないかもしれません。
Response
ここにはトレードオフがあることに気づきました。レスポンスをジェネリックにすると、リクエストが複数のクラスに分断されます。逆に、リクエストをジェネリックにすると、今度はレスポンスが分断されます。
Moya と APIKit の両方のコードを読みました。私見では、この 2 つは Swift のネットワーキングにおいて最も洗練されたアーキテクチャですが、それぞれに一長一短があります。
ネットワーキングのベストな解はまだ見つけられていませんが、今のところは、アプリの要件に応じて賢く選ぶのが最良の答えだと思います。
参考リンク
Kiri は Moya よりはるかに小さいライブラリですが、私の個人プロジェクトでは問題なく動いています。ぜひ試してみてください!