このエントリーが役に立ったらシェアをお願いします!

REST APIとは? – API設計のポイント!

このエントリーが役に立ったらシェアをお願いします!

最近は様々なサービスでWebAPIが提供されています。普段の開発をする中でもシステム連携などでAPIを作る機会が出てくるのではないでしょうか。
WebAPIの中でもREST APIなんてものもよく聞くのかなぁと思います。REST APIの設計は色々と奥が深く、なかなかおもしろい技術です。

今回はそんなREST APIを設計する上でのポイントをご紹介していきます。この記事では実装よりも設計思想的な部分を書いています。次回以降にもう少し実装に近いレベル記事を書いきます!

スポンサーリンク

REST APIとは

REST APIとはRESTの原則に沿った形で設計されたAPIを指します。
じゃあ、RESTってなんぞや?となると思いますが、参考サイトにはこんなことが書かれています。

「セッションなどの状態管理を行わない(やり取りされる情報はそれ自体で完結して解釈することができる)」(Webシステムでは、HTTP自体にはセッション管理の機構はない)、「情報を操作する命令の体系が予め定義・共有されている」(WebシステムではHTTPのGETやPOSTなどに相当)、「すべての情報は汎用的な構文で一意に識別される」(URLやURIに相当)、「情報の内部に、別の情報や(その情報の別の)状態へのリンクを含めることができる(ハイパーメディア的な書式で情報を表現する)」(HTMLやXMLに相当)

REST – e-words

色々と難しい言葉が書かれていますが、僕はざっくりと次のように解釈しています。

  • HTTPの技術を最大限活用する、シンプルな設計方法
  • 「何のリソースを」「どのように」操作するかをURIやHTTPメソッドで表現する
  • リソース指向の設計

メインとなるのはこの三点なのかなと考えています。
独立性が高くシンプルな設計になるので、HTTPを理解していればとてもわかり易く汎用性が非常に高いものを作ることができます。

APIを作る前に”流行り”を知る!

REST APIをを作る前に先人はどのような設計をしていたのかを見てみましょう。
今ではTwitterやfacebook,Github、Amazonなど大きいところではだいたいAPIを提供しているので、お手本は山ほどあります。
URL設計やリクエスト・レスポンス、HTTPヘッダなどに着目して見比べてみましょう。

Twitter REST API
レスポンスの情報量が多いので、どういった情報を返すべきか参考になります。
Cybozu REST API
共通仕様が明確に書かれているので、APIのベースを考えるときに参考になります。HTTPヘッダの拡張もしています。
Github API
個人的には一番綺麗にまとまっているAPIだと思います。リクエスト・レスポンスがRESTらしく、とても綺麗。

REST APIを作る時に考えること

実際にREST APIを作るときはシンプルであることが鉄則です。
REST APIは「何を」「どうする」というようにシンプルなインタフェースでなければならないので、APIの利用者が何を必要としているかどうやったら使いやすいか、といったことを考える必要があります。
そこで、僕がREST APIを完成させるまでに考えたことを挙げていきます。

リソースの決定

まずREST APIを作る前に「操作するリソース」を明確にし、必要となるAPIを洗い出していきます。
リソースを決定するときに考えたのは次の3点です。

APIのユーザが必要としている情報資源(リソース)
APIユーザはどんな情報を必要としているか?ブログで例えると記事,コメント,タグ,カテゴリなどの情報ですね。
リソースに対して必要な操作(CRUD)
そのリソースに対してどんな操作が必要か?ブログの記事は参照,作成,更新,削除が必要です。
リソースの親子関係
それらのリソースにはどんな関係があるか。記事にはコメントが複数付き、記事はカテゴリに属します。

気をつけなければいけないのは、リソース=データベーステーブルとは限らないということです。リソースの洗い出しはDB設計にそれとなく似ていますが、APIはあくまでインタフェースなのでひとつのリソースの中にメタデータとして関連する情報を持っていても大丈夫です。

URLの設計 – Cool URI

リソースを洗い出した後は、URLの設計に入ります。URLは非常に奥深く、様々な要素に関わってくるので慎重に設計する必要があります。ここが本記事での一番のポイントですね。WebAPIのURLをきちんと設計することで今後のWebAPIの拡張性を高めたり、開発者にとって仕様を理解しやすいものにできます。
特にAPIのURL設計で意識すべき点を挙げてみます。

  1. ひと目でAPIと分かるようなURLにする
  2. URLにAPIのバージョンを含める
  3. URLに動詞を含めず、複数形の名詞のみで構成する
  4. アプリケーションや言語に依存する拡張子は含めない
  5. リソースの関係性がひと目で分かるようにする
  6. 長くしすぎない

ちなみに良いURLはCool URIと言われ、半永久的に変わらないと言われています。
Cool URIs don’t change

では、これらを1つずつ見ていきましょう。

ひと目でAPIと分かるようなURLにする

APIを利用する開発者がURLを見た時に「あ、これAPIじゃん!!!」と分かるようにしておきましょう。実際間違えるなんてことはないと思いますが、普段開発しているサイトと切り分けられるようにしたほうが美しいです。

よくある構成としてはディレクトリに分ける場合と、サブドメインに切る場合があります。

  • http://example.com/api
  • http://api.example.com

個人的にはサブドメインを切ったほうが美しく見えます。API用のサブドメインを切ればディレクトリ構成はフリーダムに作ることができるので。。

URLにAPIのバージョンを含める

URLにAPIバージョンを含めるようにしましょう。大手が提供しているREST APIには必ずと言っていいほどバージョニングがされています。これにより、REST APIを使用する開発者がAPIのバージョンを選択しやすくなり、バージョンの切り分けも容易となるメリットが有ります。

  • http://api.example.com/1/article
  • http://api.example.com/v1/article/

URLに動詞を含めず、複数形の名詞のみで構成する

URLはリソースそのものを表し、操作(動詞)についてはHTTPメソッドで表現することがよしとされています。
また、REST APIにおいてはリソースに対し一つのURLを割り当てていくことがポイントです。

ではまず最初に好ましくないURLについて見てみましょう。

  • http://api.example.com/v1/createArticle
  • http://api.example.com/v1/article/create
  • http://api.example.com/v1/article/126/create
  • http://api.example.com/v1/article/createComment
  • http://api.example.com/v1/article/126/comment/10/create

この場合はURLを見ただけで何をどう操作するのかが明確になっていて良く見えます。しかしリソースに対して一意ではないという問題と、一つのリソースに対してCRUDの操作が必要になった場合にその操作の分だけURLが増えてしまう問題があります。あとはURLが長くなりがちです。

これを名詞のURLにすると、以下のようになります。

http://api.example.com/v1/articles
article全てを指す
http://api.example.com/v1/articles/126
articlesの中のID:126を指す
http://api.example.com/v1/articles/126/comments
articlesの中のID:126についたcomment全てを指す
http://api.example.com/v1/articles/126/comments/10
articlesの中のID:126についたcommentsの中のID:10を指す

このURLを見ただけで何のリソースなのかが分かりますね。IDをURLに含めることでリソースごとに一意のURLを割り当てることができます。
ここで、名詞を複数形にすることで全てのリソース(複数)を指す場合と、全てのリソース(複数)の中からIDを指定している場合を表現することができ、表現に一貫性を持たせることができます。

リソースの関係性がひと目で分かるようにする

URLを見ただけで、リソースがどこに属しているか分かるようにするのがベストです。
例えば、記事に属するコメントを表す場合は以下のように書いてみます。
http://api.example.com/v1/articles/126/comments/
これで記事ID126に属するコメントということが一発で分かるかと思います。

アプリケーションや言語に依存する拡張子は含めない

URLの末尾に.phpや.plなど言語に関係した拡張子を付けないようにしましょう。将来的にAPIの仕様変更で言語の変更などがあった場合に悲しいことになります。言語の拡張子がなければ、フレームワークや言語に縛られることがないので、様々な変更に対応ができます。
また、言語の拡張子はAPIのユーザには知らせなくて良い情報なので、余計なものは付ける必要がありません。そして四文字分URLが短くなります!!素敵!

URLを長くしすぎない

これは単純にURLが長すぎると実装が面倒になるということです。そして拡張性や一貫性も下がる可能性があります。あと覚えづらい。。
http://api.example.com/articles/128/comments/10/tags/10/…..
APIを利用する開発者の立場になって考えると、実装がかなりエグいことになるというのが分かりますね。。なるべくシンプルで短いURLが良いです。

HTTPメソッドを決定

前述のCoolなURLは動詞が含まれていないため、このままではCRUDの処理を切り分けることができません。そこで出てくるのはHTTPメソッドです。POSTやGETはよく知られているかと思います。HTTPメソッドには他にもHEADやOPTIONSなどあまり聞かないものも出てきます。
HTTP1.1 Method Definitions
この中でREST APIに使用するのはPOST,GET,PUT,DELETEです。
使い分けとしては以下のようになります。

POST
Createを表します。リソースを新規作成する場合に使用します。PUTによるCreateと違い、IDが自明でない場合に使用されます。その為、実質はリソースを指定(/article/10)せずに上位リソース(/article)へ更新を行っています。
GET
Readを表します。リソースを取得する場合に使用します。取得の結果は冪等になります。
PUT
Create/Replaceを表します。POSTと違い、IDが自明な場合に使用されます。URLで指定したリソース(/article/10)が存在する場合は更新(置き換え)を行い、リソースが存在しない場合は登録を行います。POSTで更新する時と違い、リソース更新が冪等となる際に使用します。
DELETE
Deleteを表します。リソースの削除をする場合に使用します。削除の結果は冪等になります。
2016/06/09 コメントでご指摘いただき、POST・PUTの説明を一部修正しました。

補足1:冪等とは?

冪等(べき等)とは何度同じ操作をしても結果が変わらない事をいいます。
イメージしづらいので実際に例を挙げてみます。

エリアIDを渡し、エリアの名前を取得する
エリアIDを何度渡しても取得できる結果は同じです。
ユーザ情報の住所を変更する
サーバに更新後の住所の値を送信するかと思いますが、何度同じ値を送信しても更新する内容は変わりません。
コメントIDを渡し、コメントを削除する
コメントIDを何度渡しても削除するのは1レコードです。

PUTでリソースの更新

補足2:クライアントがPUTとDELETEをサポートしていない場合

最近ではほとんどないかと思いますが、まれにAPIを利用するクライアントがPUTやDELETEをサポートしていない場合があります。
この場合の対処法としてはパラメータに「?_method=PUT」などと付与することでPUTの処理を返してあげるという方法が一般的です。

WebAPIを作る上でのオススメ書籍

Web API: The Good Parts
Web API: The Good Parts
美しさを意識したWebAPI設計について書かれています。リクエスト/レスポンスのベストプラクティスや、HTTPを活かした設計方法、拡張性を意識した設計方法など、かなり詳しく書かれているのでWebAPIを作ろうとしている方にはオススメです。

Webを支える技術
Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)
WebAPIというより「Web」の技術について詳しく書かれています。通常のWeb開発で利用できる技術が紹介されているのでWebエンジニアの方は必見です。
REST APIの設計をする前に読んでみると良いと思います。個人的にはかなり読みやすかったです。

最後に

いかがでしたでしょうか。ここまでポイントを色々書いてきました。他にもREST APIについて色々考えるべきことは出てくるかと思いますが、最低限のことはここでご紹介できたかと思います。次回以降はHTTPヘッダを使用したテクニックや構えておくべきパラメータなど、もう少し実装寄りのお話をしたいと思います。

スポンサーリンク

このエントリーが役に立ったらシェアをお願いします!

1この記事を書いた人
ShoheiTai
フロントエンド志向のWebエンジニア。
HTML5やWeb高速化、SEO等のフロントエンド開発が大好物。
バックエンドではCakePHP,Wordpress開発を主戦場としています。
Web開発のスパイスファクトリー株式会社創業メンバー。

イケてないコード - Webエンジニアのブログの
最新情報をいいねしてチェックしよう!

コメント

  1. 匿名 より:

    POST は Update、PUT は Create/Replace をそれぞれ表します。

    9.5 POST

    The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

    POSTメソッドはリクエストが抱合する内容を【Request-URI の下位リソース】としてサーバに受け取らせるために用いられます。

    9.6 PUT

    The PUT method requests that the enclosed entity be stored under the supplied Request-URI.

    PUTメソッドは抱合する内容を【Request-URI】に格納するよう要求します。

    POSTは既に存在する上位リソースの更新です。
    ID(URI)が自明なデータの登録はPUT、

    例: 2016/5/12 のブログエントリの登録
    PUT /blog/entry/2016/5/12

    ID生成が必要なデータの登録は上位リソースへの POST、

    例: 2016/5/12 のブログエントリへのコメント追加
    POST /blog/entry/2016/5/12/comment

    といったような使い分けになります。

    • ShoheiTai より:

      お返事が遅くなってしまい申し訳ありません。
      詳しくご説明いただきありがとうございます。とても分かりやすく勉強になりました!

      ID(URI)が自明なデータの登録はPUT
      例: 2016/5/12 のブログエントリの登録
      PUT /blog/entry/2016/5/12

      こちらは記事の中で「PUTはUpdate」と記載していたため、後ほど以下の要点で修正させていただきます。

      • PUTはURLのリソースに対する作成(Create)・更新(UpdateまたはReplace)を行う。
      • リソースが存在しなければ作成、リソースが存在すれば置き換え(更新)を行う。

      POSTは既に存在する上位リソースの更新です。

      ID生成が必要なデータの登録は上位リソースへの POST、
      例: 2016/5/12 のブログエントリへのコメント追加
      POST /blog/entry/2016/5/12/comment

      こちらについてですが、「上位リソースの更新」は実際の処理として「ID生成の必要な新規リソースの作成」ということになるので、本記事内の「POSTはCreateを表す」という表現は問題ないと考えています。
      ただ、記事内で「上位リソースの更新」についての説明は必要かと思いますので、こちらも追記させていただきます。

      ご指摘いただきありがとうございました。