🐤

TwitterAPIKit の設計方針

2022/04/05に公開

以前紹介した TwitterAPIKitの設計方針について書きたいと思います。

このライブラリを作る上で考えたことはこれだけではないですが大きく以下の3つです.

  1. メンテナンスがされなくなっても使い続けることが可能なこと
    • ライブラリのアップデートを待たずに新しい API の利用が可能なこと
  2. 他のライブラリへの依存関係を持たないこと
  3. Twitter API v1 と v2 の両方に対応すること

それぞれどういうことか説明します。

1.メンテナンスがされなくなっても使い続けることが可能なこと

よほど人気なライブラリでない限り、複数人でのメンテナンス体制は取れません。その結果ライブラリのオーナーの状況次第でメンテナンスが継続できなくなることがあります。

通常 Twitter API の仕様変更があったらメンテナはライブラリに必要な修正を行いアップデートを行う必要があります。

しかし開発が停止していたらいつまでもライブラリを経由して API を使用することができません。また停止していなくてもアップデートが行われるまでのタイムラグがあります。

その課題を解決するために、 TwitterAPIKit では以下の方針をとっています。

  1. API のパラメータを openclass にする
  2. 任意の API を自由に叩ける低レベルな API を用意する

1.API のパラメータを openclass にする

1 はパラメータを openclass にすることでライブラリ利用者側で自由に継承して変更することが可能になります。これにより、特定の API に新しいパラメータが増えるなどの変更が生じてもライブラリのアップデートを待たずに利用者側で対応することができます。
パラメータのようなものは Swift では struct で宣言することが多いと思いますが、 class にしておくことで継承できるメリットが生まれます。

2.任意の API を自由に叩ける低レベルな API を用意する

2 の低レベルな API を用意するとはどういうことでしょうか?

TwitterAPIKit では getHomeTimeline()postUpdateStatus() など Twitter API に対応した API のメソッドが生えています。これらを高レベルな API と読んでいます。

しかし Twitter に新しい API が増えた場合にはライブラリの更新を待たなければいけません。

そこでこの場合でもライブラリの更新を待たなくていいようにしました。 以下のように新しい Twitter API が増えた場合には session.send() メソッドを使うと自作した request クラスを使ってリクエストすることができます。

client.session.send(request)

https://github.com/mironal/TwitterAPIKit#low-level-api

session.send() は面倒な Twitter の認証周りをうまいことやってくれるので、シンプルにリクエストの class を作ることだけを考えれば大丈夫です。

これら大きく2つの柱によって "メンテナンスがされなくなっても使い続けることが可能なこと" を達成しています。

2.他のライブラリへの依存関係を持たないこと

TwitterAPIKit 程度の小さなライブラリの場合は他のライブラリへの依存を持つことは、その依存のメンテナンスコストに比べてメリットが無いと判断したので依存関係は持たないことにしました。

また、実際にアプリに組み込む場合にはアプリで使っている別のライブラリの依存関係との衝突が発生するの嫌なのでできるだけ小さい状態に保つ方針にしました。

3.Twitter API v1 と v2 の両方に対応すること

最初は Twitter API v2 だけに対応したものを作ろうかと考えましたが、 v2 でできることは限られているため実際にアプリケーションを作る場合には多くの場合には v1 と v2 を組み合わせる必要が出てくると思います。

その場合 V1 に対応した別のライブラリ + TwitterAPIKit(v2 のみ対応版) という構成も考えられますが、以下の理由によりやめました。

  • 現状メンテナンスが続いている Swift 向けの Twitter API v1 のライブラリが無い
  • 別々のライブラリを使うと書き味が変わってしまうため気持ち悪い
  • URLSession や認証情報を多く保持しないといけないためコードが面倒
    • v1 API を叩いたあとに v2 API 叩くときに複数の TwitterClient インスタンスを保持するのが嫌

それならばと v1 と v2 の両方に対応したライブラリを作ってしまおうと考えました。

Discussion