APIを設計していてHTTPヘッダに情報を入れることがあるけれど、その際に時間を入れたい時があります。その際にどんな形式にすればいいのかなっていう話題です。
時間というのはいろいろな形式で表現が可能です。
形式名 | 例 |
---|---|
RFC 1123 | Thu, 17 Oct 2013 23:12:00 JST |
ISO 8601 | 20131017T231200+0900 |
UNIX Timestamp | 1381999405 |
で、この中で一番何がプログラム的に取り扱いやすいかといえばUNIX Timestamp、いわゆるエポック秒かなと自分は思っています。数値だし、それにタイムゾーンの概念がないので世界に単一のタイムゾーンしか無いと思っているエンジニアが変な値を入れる危険性も少ないと思われるから。しかも開発で使う言語はほぼすべてUNIX Timestampと自前の日時表現の変換の仕組みを提供しているし。他の形式だとフォーマットをこちらで指定しなくちゃいけなかったりして面倒な場合もあります。
で、APIには一人のユーザーからのアクセス数(あるいは1アプリケーションなど)を制限する「レートリミット」という仕組みを導入しているものが多くてその際にはX-RateLimit-Limit(あるいはX-Rate-Limit-Limit)をはじめとするヘッダを使うのがデファクトスタンダードっぽいです。
ヘッダ名 | 説明 |
---|---|
X-Rate-Limit-Limit | 単位時間あたりのアクセス上限 |
X-Rate-Limit-Remaining | アクセスできる残り回数 |
X-Rate-Limit-Reset | アクセス数がリセットされるタイミング |
TwitterがAPI version 1.1で導入したのがはじめかな(調査中)と思うのですが、今は普通に使われています。例えばGitHubもちょっと名前は違いますがほぼ全く同じです。Foursquareもほぼ同じ。その他たくさんあります。こんなまとめもありました。
1 2 3 4 |
Status: 200 OK X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4999 X-RateLimit-Reset: 1372700873 |
Rate-LimitとするかRateLimitとするかはどっちにするべきかよくわかりませんが、自分ならRate-Limitとするかなと思います。
そしてこの中にX-Rate-Limit-Reset(X-RateLimit-Reset)というヘッダがあって(Foursquareなどこれを返さないものもある)、これはAPIの利用制限が解除される時間を表しますが、UNIX Timestampで値が入ってるケースが多いのです。TwitterもGitHubもそうです。
でもこれに異議を唱えてる人がいて、Best Practices for Designing a Pragmatic RESTful APIという記事があり、その中でUNIX Timestampは使うな、解除までの秒数(デルタ秒)を使え!と強く主張していました。この記事を書いたVinay Sahniさんの主張では、HTTPでは使っていい日付形式はRFC1123で、UNIX Timestampは使えないんだから仕様に反してるんだよ!使うんだったらRFC1123形式を使うべきだ、と書かれています。
え、そうなのか、と改めてHTTP 1.1の仕様に立ち返ってみたところ、確かにHTTPでは時間を表すのに、以下の3つの形式か、デルタ秒を使わないといけないと書いてありました。
形式名 | 例 |
---|---|
RFC 822, updated by RFC 1123 | Sun, 06 Nov 1994 08:49:37 GMT |
RFC 850, obsoleted by RFC 1036 | Sunday, 06-Nov-94 08:49:37 GMT |
ANSI C’s asctime() format | Sun Nov 6 08:49:37 1994 |
定義で言うとrfc2616で以下のようになってます。
1 |
HTTP-date = rfc1123-date | rfc850-date | asctime-date |
そしてたしかに例えばきちんと定義されているHTTPヘッダを見てみると、例えばRetry-Afterは以下のようになっています。
1 |
Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds ) |
そうだったのか…ということでHTTPのヘッダにUNIX Timestampを使うのは厳密にはダメらしいんですけど、やっぱりUNIX Timestampはハンディだし使いたいなあと思っているこの頃です。
ちなみにHerokuも使っていますね。みんなこの辺を知っててあえてUNIX Timestampを選んだんでしょうか。
X-Request-Start: unix timestamp (milliseconds) when the request was received by the router
個人的にはUNIX Timestampを使い続けたいところ。例えばスマフォアプリのサーバクライアント連携とか、半ばプライベートなAPIの場合は使ってしまっていい気もしますが、一般公開するAPIの場合はどうすべきか悩むところです。デルタ秒だといつを基準としたデルタ秒だよ、という気もするし…まあDateヘッダで示された時間からですね。ただ、UNIX Timestampも随分利用されてきているので、仕様があとから追いついていく可能性はあるような気がします。