RESTful Hypermedia API 概要編

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

モバイルアプリサービス部の五十嵐です。

最近『ハイパーメディアAPI』という言葉を知って、興味が湧いたので調べてみました。これから何回かに分けて、ハイパーメディアAPIとは何か、Ruby on Railsでのサーバ側の実装方法、クライアント側の実装方法などを紹介していきたいと思います。

1回目の本記事では、ハイパーメディアAPIの概要説明として、用語の説明や登場の背景、フォーマットなどを紹介していきます。特に注意がない限りAPIWeb APIを指します。なお、用語の定義というのは往々にして議論の対象になりやすいですが、ここでで説明するのは厳密な定義ではなく広義の定義と捉えてください。それでも私の認識に誤りがある場合は、そっとご指摘いただけると幸いです。

用語の説明

RESTful APIとは

まずはRESTful APIについて簡単におさらいをします。RESTは分散された情報を扱うためのアーキテクチャのひとつであり、RESTのアーキテクチャで設計されたAPIがRESTful APIとなります。

RESTful APIは以下の様な特徴があります。

  • リソースと呼ばれるシステムで扱うデータをURIで一意に表す
  • HTTPのメソッドによって操作を表す

以下はRuby on RailsにおけるRESTfulなURIの一覧です。リソース名とidを用いてURIでリソースを一意に識別子、CRUD操作に対しては対応するHTTPメソッドが用意されています。

    Prefix Verb   URI Pattern                   Controller#Action
      data GET    /data(.:format)               data#index
           POST   /data(.:format)               data#create
 new_datum GET    /data/new(.:format)           data#new
edit_datum GET    /data/:id/edit(.:format)      data#edit
     datum GET    /data/:id(.:format)           data#show
           PATCH  /data/:id(.:format)           data#update
           PUT    /data/:id(.:format)           data#update
           DELETE /data/:id(.:format)           data#destroy

RESTはアーキテクチャですから、データの内容については特に定められていません。

Hypermedia APIとは

次にHyperMediaについてです。Hypermediaはテキストや画像など様々な情報(メディア)をリンクを使って繋いだ情報媒体を指します。よく例としてあげられるのがWorld Wide Webです。WWW上で、Webページからリンクを辿って別のWebページヘ行く様子を想像いただければ良いかと思います。

Hypermedia APIは、APIのレスポンスに関連する別のリソースのリンクURIが含まれており、APIの利用者は関連するリソースを事前に知らなくてもリンクURIを辿ることで関連する情報を取得したり操作することができます。

この「事前に知らなくても」ということが重要で、純粋なRESTful APIの場合は、APIの利用者はAPIの全てのリソースを知ったうえでクライアント側の実装をする必要があります。そのため、実装にはリソースの定義が直接埋め込まれることになり、APIを変更した場合に利用者に与える影響が大きいということが問題になります。

一方のHyperMedia APIは、利用者はAPIのリソースを全て知らなくてもリンクURIを辿ることで良いわけですがから、APIの変更による影響は小さくなります。ただし利用者もAPIのデータ構造を知らなければ何もできませんので、メディアタイプとして標準化されたJSON拡張フォーマットが使われたり、クライアントと呼ばれるAPIのParserとセットで使うようです。(JSON拡張フォーマットやクライアントについては次回以降で詳しく紹介します。)

説明だけではわかりにくいので、Hypermedia APIのサンプルを1つ紹介します。これはJSON APIというAPIにおけるJSONフォーマットの仕様を定めたサイトにあるサンプルです。少し長いですが見ていただくとイメージが湧くかと思います。

{
  "links": {
    "self": "http://example.com/articles",
    "next": "http://example.com/articles?page[offset]=2",
    "last": "http://example.com/articles?page[offset]=10"
  },
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!"
    },
    "relationships": {
      "author": {
        "links": {
          "self": "http://example.com/articles/1/relationships/author",
          "related": "http://example.com/articles/1/author"
        },
        "data": { "type": "people", "id": "9" }
      },
      "comments": {
        "links": {
          "self": "http://example.com/articles/1/relationships/comments",
          "related": "http://example.com/articles/1/comments"
        },
        "data": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    },
    "links": {
      "self": "http://example.com/articles/1"
    }
  }],
  "included": [{
    "type": "people",
    "id": "9",
    "attributes": {
      "first-name": "Dan",
      "last-name": "Gebhardt",
      "twitter": "dgeb"
    },
    "links": {
      "self": "http://example.com/people/9"
    }
  }, {
    "type": "comments",
    "id": "5",
    "attributes": {
      "body": "First!"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "2" }
      }
    },
    "links": {
      "self": "http://example.com/comments/5"
    }
  }, {
    "type": "comments",
    "id": "12",
    "attributes": {
      "body": "I like XML better"
    },
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "9" }
      }
    },
    "links": {
      "self": "http://example.com/comments/12"
    }
  }]
}

このAPIレスポンス全体はarticleリソースのid:1の情報を扱っているようです。一番上にlinksがありますが、これは自身のURI、次のarticleのURI、前のarticleのURIを表しています。dataの中にはこのarticleの情報と、関連する情報がrelationshipsの中で表現されています。includedの中にはrelationshipsの情報が表現されています。

RESTful Hypermedia APIとは

ここまでの説明でもうお分かりかと思いますが、RESTful Hypermedia APIはRESTful APIのアーキテクチャを用いてAPIレスポンスをHyperMediaなデータフォーマットにしたものです。

所感

ハイパーメディアAPIの設計方法はまだ混沌としていますが、いずれデファクトスタンダートが定まってくるとAPI開発の新たなパラダイムになるのではという可能性を感じています。ハイパーメディアAPIを使うことでいかに利用者が扱いやすいAPIができるか、考えていきたいと思います。

参考