REST API (RESTful API)は API の PATH をリソースの PATH に見立てて、 API のエンドポイントを決めていく、というのは皆さんご存知のことです。
単純なリソースの PATH
例えば、
id=1
の動画はGET /videos/1
id=3
の画像はGET /images/3
のようになります。
ここまでは簡単に理解できると思います。
検索 API の PATH は?
しかし「検索のAPI」などと言われた時にこまることがあります。やりがちなのが「動画検索のAPI」であれば GET /videos/search/:keyword
といったエンドポイントです。
これも悪くはないかと思いますが、 id=1
の動画が GET /videos/1
なのであれば、 /videos/search/:keyword
は、id=search
の動画のなにか、と思うかもしれません。
検索は「リソース」ではなくて「アクション」なので、何も考えずに PATH に登場させると、違和感のある PATH になってしまうことがあるのです。僕もこの点については非常に悩んできました。
ではどうするのか
アプローチは大きく分けて2パターンあります。
- 完全な REST の形は諦めて、リソースとかぶらない形式でエンドポイントを作る
- すごく頑張って REST の形を維持しようとする
だいたい 1 のパターンで解決することが多いように思います。
完全な REST の形は諦めるパターン
よく見るのが GET /search/videos
のような形です。これは「検索」します。検索されたリソースの中から「動画」を見ます、のような捉え方をします。twitterのAPIはこれです。
例えば、キーワード検索であれば GET /search/videos?keyword=abc
のような形になるかと思います。GET /videos/search
のようなパターンと違って、PATHがコンフリクトすることはありません。
画像を検索する場合は GET /search/images?keyword=abc
のようになります。
もし画像と動画まとめて検索するなら GET /search?keyword=abc
となります。
あるいは、ニコニコ動画のような「動画投稿サービス」で、検索対象のリソースが動画しかないよ!みたいな場合も単に GET /search?keyword=abc
でもいいです。
他には以下のような選択肢があると思います。
GET /actions/search/videos?keyword=abc
GET /search/:keywrod/videos
GET /search-videos?keyword=abc
GET /actions/search-videos?keyword=abc
僕の中で最近ブームなのが GET /search-videos
のような形です。GET /search/videos
とするとどうしても videos
って何? videos
以外にもなにか指定できるの?みたいになりますし、他の PATH とも絶対かぶらないので好きです。
REST を追求してくパターン
REST を追求していくなら GET /videos?keywrod=abc
だとか GET /videos?searchByKeywrod=abc
みたいな形になるかと思います。
一見きれいですが、 GET /videos
に大量の分岐が発生してしまう可能性があるので、保守が大変担ってしまうリスクはあります。その点を考えると、最初の「完全な REST の形は諦めるパターン」のほうが無難かなと思います。
Search以外の例
例えば GET /videos/recent
もそれっぽいですが、 GET /recent-videos
とかのほうが個人的にはスッキリしてるんじゃないかなという気がしています。
これは「アクション」というよりも「エイリアス」みたいな気がしますね。直近x件の動画情報へのエイリアスという感じです。
まとめ
search
のような「リソース」ではないものを REST API に組み込むにはどうしていけばいいの?というお話でした。