Web API(REST API)のURL設計

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Web API(REST API)のURLの設計って、迷いませんか?

Web APIのURLは「これが正解」というものが無く、決め手に欠き、迷ってしまいがちだと思います。有名なサービスの例を見てもそれぞれ個性があります。

ですが、いくつかの設計方針を用意してそれにはめていくことで、ある程度機械的に進めることができると思います。

この記事では、私が実際に行ったWeb APIのURL設計で用いていた設計方針(のようなもの)について、いくつか書いてみます。

基本形

URLでリソースを表現する際は名詞の複数形を使います。例えばproduct(製品)というリソースを扱うWeb APIの場合、Httpのメソッドと組み合わせて、以下のようなAPIにすることが考えられます。

POST /products 1件のproductを生成
PUT /products/111222 productの属性を変更
DETETE /products/111222 productを削除
GET /products/111222 productの属性を取得
GET /products productの一覧取得

111222は製品のIDです。

ここまでは割と一般的だと思うのですが、実際にWeb APIを設計していると、もう少し複雑なものも出てきます。

自分のリソース、他人のリソース

例えばarticles(記事)というリソースがあったとき、

GET /articles/333444

とすると、その記事が取得できるAPIになりそうですが、333444の部分を他人の記事のIDにした場合、それは取得できてよいのでしょうか。「自分の記事は取得できるが、他人の記事は権限がある場合のみ取得できるようにしたい」とするケースもあるとでしょう。

その場合、まず「GET /articles/333444」の方は自分の記事のみを取得するAPIとします。 そして、他人の記事を取得するAPIを以下のように別途用意します。

GET /users/999888/articles/555666

このように/users/999888の部分で対象ユーザーを明示します。(999888はユーザID、555666は記事のIDです。) 別のAPIにすることで、それぞれの機能も明確になり、実装もしやすいと思います。

GET,POST,PUT,DELETEだけでは表現しづらいもの

世の中の機能がすべてGET,POST,PUT,DELETEで表現できたらよかったのですが、これらだけだと苦しいこともあります。私が遭遇した例では「印刷する」「通知する(クライアントからサーバーに)」といったものがありました。

私がとった方法は、例えば処理の完了をクライアントからサーバーに通知するためのAPIは、

POST /processes/777888/notify

のように、HttpメソッドはPOSTとし、リソースを表すURLの末尾に機能を表す動詞(この場合はnotify)をつけるようにしました。

こうなってくるともはや何でもありな気もしてきますが、一応こういう例外措置ルールがあると、困った時救われます。

複数一括削除

いくつかのリソースをまとめて削除するAPIを考えます。

削除なのでDELETEメソッドを使いたいところですが、「DELETE /articles」のようにしてしまっては、/articlesという記事の集合リソース自体を削除するように解釈され、よくありません。

というわけで、これも「POST+末尾に動詞」で表現します。削除対象の記事のIDはbodyで指定します。

POST /articles/delete

最後に

今回、Web APIのURL設計について、実体験を元にいくつか書いてみました。

ですがもちろんここに書いたことが正解というわけではありませんし、つっこみどころも多いかと思いますが、この記事が少しでも参考になれば幸いです。

参考書籍

webapi-goodparts

Web API The Good Parts

https://www.oreilly.co.jp/books/9784873116860/

Web APIの設計については、この本によくまとまっています。おすすめです。 今回の記事でも参考にさせていただきました。