Webエンジニアの日常とリーグオブレジェンド

Webエンジニアとして働いている猫のブログ。EmacsとMySQLとリーグオブレジェンド(LoL)が好物。主に技術的な記事かLoLの記事を書く。

REST API の URL(PATH)をどう作っていくか - Search の例

f:id:yoshiki_utakata:20191008011153p:plain

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パターンあります。

  1. 完全な REST の形は諦めて、リソースとかぶらない形式でエンドポイントを作る
  2. すごく頑張って 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 に組み込むにはどうしていけばいいの?というお話でした。