センサー情報取得のためのRestfulなインタフェース

Webアプリからセンサ情報を取得するために使用するRestfulなインタフェースを考えてみました。

リソースの決定

まずRestfulなインタフェースを作る前に「操作するリソース」を明確にします。リソースを決定するときに考えたのは次の3点です。

使用するユーザが必要としている情報資源(リソース)
センサーを使ってユーザがどのように制御したいか?例えば、複数のユーザで使用したいときは、使用するセンサーを指定して名称を割り当てたり、利用するセンサーのスケジューリングなどの情報をリソースとします。
リソースに対して必要な操作(CRUD)
そのリソースに対してどのような操作が必要か?システムのセンサーの一覧の取得、センサータイプに基づくセンサーの生成、センサー情報の取得、センサー情報(名称、構成など)の更新、センサー情報の削除など、参照,作成,更新,削除(「CRUD」と呼ぶ)が必要です。
リソースの親子関係
それらのリソースにはどんな関係があるか。センサーはグループ化され、名称によりスケジューリングする機能を持たせる場合などは、グループやスケジューリングが親と考えます。

URLの設計

リソースを洗い出した後は、URLの設計に入ります。次に、URL設計で意識すべき点を挙げます。

  1. ひと目でRestfulなインタフェースと分かるようなURLにする
  2. 普段開発しているサイトと切り分けられるよう設計します。よくある構成としてはディレクトリに分ける場合と、サブドメインに切る場合がありますが、次のように、サブドメインを切ればディレクトリ構成は自由に作ることができるので、美しく見えます。

    • http://api.example.com
  3. URLに動詞を含めず、複数形の名詞のみで構成します
  4. URLはリソースそのものを表し、操作(動詞)についてはHTTPメソッドで表現します。また、Restfulなインタフェースでは、リソースに対し一つのURLを割り当てます。

    • http://api.example.com/sensors
      sensors全てを指す
    • http://api.example.com/sensors/126
      sensorsの中のセンサーID:126を指す
    • http://api.example.com/sensors/126/state
      sensorsの中のセンサーID:126のstateを指す
  5. リソースの関係性がひと目で分かるようにする
  6. URLを見ただけで、リソースがどこに属しているか分かるように設計します。例えば、センサーのstateを表す場合は次のように記述します。

    • http://api.example.com/sensors/126/state
      sensorsの中のID:126のstateを指します。これでセンサーID:126のstateということが分かります
  7. アプリケーションや言語に依存する拡張子は含めない
  8. URLの末尾に.phpや.plなど言語に関係した拡張子を付けない。

  9. 長くしすぎない
  10. これは単純にURLが長すぎると実装が面倒で、覚えづらく、拡張性や一貫性も下がる可能性があります。

HTTPメソッドの設計

前述のURLは動詞が含まれていないため、HTTPメソッド「POST」「GET」「PUT」「DELETE」を使用して、CRUDの処理を切り分けます。使い分けとしては以下のようになります。

POST
Createを表します。リソースを新規作成する場合に使用します。PUTによるCreateと違い、IDが自明でない場合に使用されます。その為、実質はリソースを指定(/sensors/10)せずに上位リソース(/sensors)へ更新を行っています。
GET
Readを表します。リソースを取得する場合に使用します。
PUT
Create/Replaceを表します。POSTと違い、IDが自明な場合に使用されます。URLで指定したリソース(/sensors/10)が存在する場合は更新(置き換え)を行い、リソースが存在しない場合は登録を行います。
DELETE
Deleteを表します。リソースの削除をする場合に使用します。

HTTPのbody/Response

HTTPのrequestに設定するbodyとそのResponseは、JSONフォーマットにします。

  1. sensorの生成(Postメソッド)
    センサーの名称やソフトウェアバージョンなどを指定してセンサーを生成します。
    【Body】

    {
        "state": {
            "presence": false
        },
        "name": "living room",
        "swversion": "1.0",
        "uniqueid": "12345678",
    }
    

    【Response】

    {
        "success":{"id": "4"}
    }
  2. sensor情報の取得の生成(Getメソッド)
    センサーの名称や状態、センサー情報を取得します。

    【Response】

    {
        "state":{ 
            "buttonevent": 34, 
            "lastupdated":"2013-03-25T13:32:34", 
        },
        "name": "living room", 
        "uniqueid":"12345678",
        "swversion":"1.0", 
        "sensorInfo":{ 
            "Temperature": 25.2, 
            "Pressure ":1010.8, 
            "Humidity": 70.5, 
        },
    }

認証の設計

RESTfulなインタフェースは状態を持ちません。つまり、認証に関して cookie やセッションを使うことはできず、代わりに認証信用情報のようなものを使う必要があります。

SSL の利用を前提とすることで、この信用情報は非常にシンプルなものになります。ランダムに生成された文字列をアクセストークンとして、BASIC 認証のユーザネームフィールドに入力します。この方法の優れている点は、ブラウザで扱いやすいことです。未認証の状態であれば、ブラウザはアクセストークンの入力を求めるプロンプトを表示します。

Google の WebAPI の設計は、トークン認証で行います。

AuthorizationヘッダにBearer {Access Token}という形で指定します。
またaccess_tokenやoauth_tokenをリクエストパラメータにすることも可能です。
?access_token={Access Token}
?oauth_token={Access Token}