/var/log/messages

Jun 22, 2014 - 5 minute read - Comments - misc

http api design

以下なドキュメントを発見しておりまして。

なんとなくメモをとってみました。

Contents として以下が列挙されています。

  • 適切なステイタスコードを戻しなさい
  • 戻すことができる全てのリソースを戻しなさい
  • リクエストボディに含まれるシリアライズされた JSON を受け付けなさい
  • ID じゃなくて UUID 使った方が良いですよ
  • 標準的なタイムスタンプを使いましょう
  • UTC 時刻は ISO8601 フォーマットで使いましょう
  • 一貫性のあるパスフォーマットを使いましょう
  • 小文字とダッシュを使いましょう
  • 外部キーのリレーションは入れ子に
  • 利便性をはかるため non-id dereferencing をサポートしなさい
  • エラーの場合のレスポンスボディについて
  • ETag ヘッダを含めなさい
  • Request-Id ヘッダを API レスポンスに含めなさい
  • Pagination について
  • rate limit ステイタスを見せてあげなさい
  • Accepts ヘッダにバージョンを
  • パスの記述について入れ子は最小限に
  • machine-readable な JSON schema を使いましょう
  • human-readable なドキュメントの提供
  • 実行可能な example の提供
  • API がどの程度安定しているかの情報開示
  • TLS 使いなさい
  • 見やすい JSON 表示をデフォルトでサポートしなさい

ということで中身をもう少しきちんと確認してみます。

適切なステイタスコードを戻しなさい

例えば成功した旨のレスポンスは以下であるべき、とのこと

  • 200 : GET あるいは同期的な DELETE および PATCH リクエストが成功した場合
  • 201 : 同期的な POST が成功した場合
  • 202 : 非同期な POST, DELETE, PATCH が受け付けられた場合
  • 206 : GET は成功したけど部分的な応答のみ (paginate な記述見れ、とあります)

あと エラーの場合何を戻すか、というあたりについては HTTP response code spec 見なさい、という事も書いてあるので別途確認してみます。

戻すことができる全てのリソースを戻しなさい

POST, DELETE, PATCH などのリクエストが成功した場合 (200, 201) にも必要な情報を全部戻しなさい、とのこと。ただ、202 な場合は無理だよね、とのこと。

リクエストボディに含まれるシリアライズされた JSON を受け付けなさい

リクエストボディは JSON 指定の方が助かります。つうか form から送信する訳ではないんだからこれで良かろうに、と思うのですが (ry

ID じゃなくて UUID 使った方が良いですよ

Ruby だと uuidtools という gem で以下なカンジで生成できる模様。

UUIDTools::UUID.random_create

つうか PostgreSQL だと uuid なカラムを主キーにできたりするんですね。これはこれは。

標準的なタイムスタンプを使いましょう

つうか created_at と updated_at なタイムスタンプをデフォで戻しましょう、なのか。

UTC 時刻は ISO8601 フォーマットで使いましょう

そしてタイムスタンプのフォーマットは ISO8601 を、とのこと。あと UTC 使え、って書かれてますね。

以下な記述なので

"finished_at": "2012-01-01T12:00:00Z"

UTC 時刻ですね。ちなみに twitter だと以下な書式。

"Mon Jan 03 15:17:31 +0000 2011"

このあたり色々な意味で興味深いですね。

一貫性のあるパスフォーマットを使いましょう

Resource names

リソースの名前はシステムで一つだけなのが明確になっていない限りは複数形を使うべき、ということなのかどうか。

Actions

確かに RESTful な API だと action というのがパスに入ってくることはあまり無いですね。とは言え必要な場合はこうしましょう、というのが指定されてます。

小文字とダッシュを使いましょう

javascript なんかでアンスコ使うケイスがありますね、とありますが。とは言えダッシュとアンスコどっちが、ってソレは宗教になってそうで怖い。

外部キーのリレーションは入れ子に

これも確かにこうなってた方が分かりやすいです。例えば以下な形と

{
  "name": "service-production",
  "owner_id": "5d8201b0...",
  ...
n}

以下な形で

{
  "name": "service-production",
  "owner": {
    "id": "5d8201b0..."
  },
  ...
}

owner な情報に追加を、という場合のインパクトとしては (修正が入るって意味では同じかもしれませんが) 入れ子になってた方が、とは思います。

つうかこのあたり、Rails で、ってなると戻すレスポンスボディって View とかで雛形を定義できるんでしたっけ (後で調べる

利便性をはかるため non-id dereferencing をサポートしなさい

これ、UUID なソレを別名で、ってことなのかどうか。

エラーの場合のレスポンスボディについて

  • machine-readable なエラー id
  • 人間-readable なエラー message
  • 問題解決のための url

を、とのこと。出てき得るエラーについてはドキュメントにしておけ、ってのも成程。

ETag ヘッダを含めなさい

全てのレスポンスについて ETag ヘッダを入れれ、とのこと。これ、不勉強で知らなかったんですが良いですね。

  • あるリクエストで ETag ヘッダ戻す
  • クライアントでキャッシュしつつ ETag な値も保管
  • 同じリクエストを発行する時、If-None-Match ヘッダにその値を含めてリクエスト
  • ETag 値の比較をして一致してれば 304 Not Modified を戻す

HEAD で云々、よりも良いです。あと pagination がらみのソレで If-Range というヘッダもあるみたいですね。

Request-Id ヘッダを API レスポンスに含めなさい

デバッグ時に、とのこと。こーゆー地味な努力って必要ですよね。なんとなくどこかに文句言ってる風ですがご容赦下さい。

Pagination について

content-Range ヘッダについて云々。というか Rails ってこのあたりどうなってるのかな。別途確認の方向にて。

rate limit ステイタスを見せてあげなさい

rate limit を設定しているのであれば RateLimit-Remaining というレスポンスヘッダを戻してあげなさい、との由。

Accepts ヘッダにバージョンを

以下なフォーマットで、とのこと。

Accept: application/vnd.heroku+json; version=3

クライアント側で検知して云々、なのか。

パスの記述について入れ子は最小限に

入れ子になってるからと言ってその通りにするな、と。たしかに id 使ってるのであれば

/orgs/{org_id}/apps/{app_id}

/apps/{app_id}

で OK ですよね。

machine-readable な JSON schema を使いましょう

prmd って何だろ。ここ別途確認の方向ってことで。

human-readable なドキュメントの提供

む、ここでも prmd って出てくるな。以下らしい。

gem ですね。これ使って、なのかどうか。

実行可能な example の提供

ここでも prmd 出てきますね。確かにサンプルなソレで云々するのであれば API が戻すであろうサンプルな JSON を戻すことは可能なのか。

API がどの程度安定しているかの情報開示

たとえば

  • prototype
  • development
  • production

なフラグで安定性を表現しなさい、とのこと。以下を見なさい、とありますね。別途確認ってことで。

TLS 使いなさい

できれば SSL 使おうね、という理解で良いのかどうか。

見やすい JSON 表示をデフォルトでサポートしなさい

属性ごとで改行入れて差し上げて、という理解で良いのかな。pretty-print なスイッチがあれば良いのかどうか。

追記

prmd 調べてたら以下なドキュメントを発見してます。

今日の夜メシ git push な deploy 環境作ってみた

comments powered by Disqus