Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What is going on with this article?
@koriym

メディアタイプとALPSプロファイル

こんにちは。
弁護士ドットコムのテクニカルアドバイザー@koriymです。
この記事は 弁護士ドットコム Advent Calendar 2020の10日目の記事です。

昨日はSREの@t2ynkmrさんの「ECSのデプロイ方法を見直して任意のタイミングでコミットハッシュをタグに使ったイメージをデプロイできるようにした」でした。(すごい事してます!)

メディアタイプとALPSプロファイル

この記事では初めにメディアタイプの中でもドメイン固有のメディアタイプに注目します。次にプロファイルリンクを使ってアプリケーションセマンティクスを与える方法や、そのプロファイルを情報設計(インフォメーションアーキテクチャ IA)のツールとして使う事を説明します。

記事を通じてインターネットの初期から存在したWebにセマンティクスを与える(対象とするコンテントの意味をマシンに教える)仕組みを、次世代のAPI開発に応用する方法を考察します。

メディアタイプ

Media Typeは、ファイルやインターネット上で転送されるコンテンツの形式を表現する識別子である。 (wikipediaより)

Content Type1やMIME Type2とも呼ばれますが、現在、Media Typeが正しい呼び方です。
メディアタイプはIANA3 が管理していて、一覧は メディアタイプレジストリにリストされています。

例えば最も有名なメディアタイプに text/html があります。IANAレジストリでは、そのメディアタイプの登録者4 、このメディタイプの利用するアプリケーションは何か5、詳細仕様はhttp://www.w3.org/TR/html で定義されている といったことが分かります。

ドメイン固有のメディアタイプ

application/jsonがどんな内容でも扱えるのに対して、application/problem+jsonRFC7807 で定義されたクライアントにエラー情報を伝えるためのメディアタイプです。HTTPのエラーコード以上の情報をJSONオブジェクトで伝えることができます。標準を使えば、各社各サービスでエラーを発明する必要はありません。多くのメディアタイプは拡張性があり、アプリケーション固有のエラー情報も既存のメディアタイプに付加できます。

text/htmlapplication/jsonはあらゆる事に関し記述する事ができるジェネリックメディアタイプです。それに対してapplication/problem+jsonのように、特定ドメインの利用のみに使うメディアタイプをドメイン固有のメディアタイプと呼びます。

以下はapplication/problem+jsonの例です。

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json

{
 "type": "https://example.net/validation-error",
 "title": "Your request parameters didn't validate.",
 "invalid-params": [{
   "name": "age",
   "reason": "must be a positive integer"
  }]
}

上記エラーメッセージのtypetitleは、単に人間が読んで理解できるだけでなくapplication/problem+jsonを理解するクライアントにとってはそれが特別な意味を持つ語として扱うことができます。

vendor固有のメディアタイプ

メディアタイプレジストリにはvndツリープリフィックスが特定のvendorのためのメディアタイプもあります。

他にも個人/実験のためのprs や未登録を表すxなどのツリープリフィックスがあります。

メディアタイプによってリソース表現で表されるセマンティクスを理解でき、使われる言葉と正確な意味を結びつけることができます。アプリケーションがメディアタイプによってコンテンツをどのように取り扱うかを決定することができます。

プロファイル

では私たちが作成するアプリケーションやAPIも、利用者のためにセマンティクスを定義したメディアタイプを用意すればいいでしょうか? 例えばapplication/vnd.bengo4.lawer-listのように? 6 もっといい方法があります。それがプロファイル7です。

プロファイルリンクリレーションは既存のメディアタイプにアプリケーションのための追加情報を付与するための仕組みです。例えば既存のメディアタイプtext/htmlapplication/jsonに対して、追加のアプリケーションセマンティクス8を指定します。

アプリケーションやAPIで使用する言葉の意味をアプリケーションセマンティクスとして、HTTPリクエスト・レスポンスの振る舞いをプロトコルセマンティクスとして定義するとアプリケーションやAPIのマニュアルになります。

HTTPヘッダーにプロファイルをリンクします。

Content-Type: application/json
Link: <https://dev.twitter.com/docs>; rel="profile"

JSONレスポンスの内容はprofileリンクで表されたURLを見ればその意味や使い方を知ることができます。これはREST制約の4つの統一インターフェイス制約((a) リソースの識別、(b) 表現によるリソースの操作、(c) 自己記述的メッセージ、(d) アプリケーション状態のエンジンとしてのハイパーメディア)の中の1つ、自己記述的メッセージ の特徴です。9

プロファイルのフォーマットに規定はなく、人間がそのアプリケーションのアプリケーションセマンティクスとプロトコルセマンティクスを理解することができればOKです。HTMLやMD、あるいはプレーンテキストで記述してあっても構いません。

ALPS

プロファイルを特定フォーマットで記述して人間にも読む事ができるだけでなく、マシンにも解析可能なものにしようとするのがALPS (Application-Level Profile Semantics)です。

ALPSフォーマットは、解決策ではなく問題を記述することに集中できるように設計されています。URLやステータスコード、HTTPメソッドのようなものはドキュメントの一部ではありません。その代わりに、アクション(read, write, submit, approve など)やデータのプロパティ(familyName, givenName など)が含まれています。

userName を説明する「userNameはユーザーの名前です」という自然言語の文章の意味をマシンが理解することはできませんが、userNameというのが何か特別な意味のある語で、それがUserリソースに含まれ、user-registrationアクションを行うときに必要な語であるということは定義することができます。

セマンティクス

アプリケーションで使う語を定義するのはALPSの重要な役割です。

意味

{"id": "articleBody", "type": "semantic"}

これは ALPSアルプスドキュメントの一部で"articleBody" という語句を定義しています。この段階ではarticleBodyの意味は定義されていません。アプリケーションにはarticleBodyという語があるという事を定義しているだけです。10

意味を記述するのはdocを使います。

 {"id": "articleBody", "type": "semantic", "doc": {"value": "記事の本文"}}

自然言語で説明するより、もっといいのはボキャブラリサイトにリンクする事です。defを使います。

 {"id": "articleBody", "type": "semantic", "def": "https://schema.org/articleBody"}

schema.orgarticleBodyにリンクすることで意味を定義しました。このようなボキャブラリのサイトは他にdublincore.orgactivity stream があります。

語句を定義した事で、このアプリケーションでarticleBodyを使うときに説明はもう必要ありません。APIの定義で繰り返し同じ文章で説明する必要はなくなります。ボキャブラリのサイトを利用することで表記ゆれもなくなり、文化的によりニュートラルな言葉を使うことができます。11

このarticleBodyなど定義した語句をセマンティックディスクリプタ(意味的記述子)と呼びます。ALPSドキュメントはこのセマンティックディスクリプタ定義の集合です。

分類

セマンティックディスクリプタは他のセマンティックディスクリプタを含む事ができます。

{
  "id": "BlogPosting", "type": "semantic", "def": "https://schema.org/BlogPosting",
  "descriptor": [
    {"href": "#articleBody"},
    {"href": "#dateCreated"},
  ],
  {"id": "articleBody", "type": "semantic", "def": "https://schema.org/articleBody"},
  {"id": "dateCreated", "type": "semantic", "def": "http://schema.org/dateCreated"}
},

上記の例はBlogPostingブログ記事がarticleBodyブログ本文とdateCreated作成日付を含んでいることを表します。#を使ってインラインリンクしています。多くの場合、リソース表現(webページやAPI)は特定のセマンティックディスクリプタの集合です。

リンク

リソース間の遷移は以下の3つのタイプのいづれかで表すことができます。

  • safe リソース状態が変わらない安全な遷移です。HTTPだとGETです。
  • unsafe リソース状態が変更され冪等性がない遷移です。HTTPではPOSTです。
  • idempotent リソース状態が変更され冪等性がある遷移です。HTTPではPUTもしくはDELETEです。

以下はBlogPostへの安全な遷移を表しています。遷移先はrtで示します。

{"id": "goBlogPost", "type": "safe", "rt": "#BlogPost"},

遷移に何かセマンティクスが必要な場合には同じようにdescriptorで含みます。

{"id": "goBlogPost", "type": "safe", "rt": "#BlogPost", 
  "descriptor": [{"href": "#id"}]
}

これらのディスクリプタの集合を配列として以下のようになフォーマットでまとめるとALPSドキュメントになります。

{
  "alps": {
    "title": "...",
    "doc": {"value": "..."},
    "descriptor": [
      {"id": "descriptor1", ...},
      {"id": "descriptor2", ...},
      {"id": "descriptor3", ...}
    ]
  }
}

下記の例もご覧ください。

作成したALPSドキュメントはasdを使ってアプリケーションステートダイアグラムにしたり、unifiedを使ってOPEN APIなどIDLに変換することができます。

JSONの入力に不安や不満がありますか? JSON Schemaを使った入力は補完もバリデーションも効くのでスムーズです。IntelliJやVS CodeなどJSON Schemaをサポートしたエディタをお使いください。

次のスキーマを設定してALPSドキュメントを始めてください。XMLやYAMLからの変換ツールもあります。

ASD (Application State Diagram)

アプリケーション状態

アプリケーション状態とは、クライアントとサーバーのやりとりでクライアントがどこに位置しているかという状態です。例えばECサイトでは商品を見ているのか、注文して支払いにしているのか、といったURLとして反映されるクライアントのリクエスト位置の情報です。サーバーから与えられるリンクによってアプリケーション状態が遷移するのがRESTです。12 13

ダイアグラム

asdツールはALPSドキュメントからアプリケーション状態遷移図を描画します。ダイアグラムはSVGでレンダリングされ、四角で表されたのがアプリケーションステート、矢印で表されているのがその遷移です。クリックしてその詳細を見る事ができます。

ダイアグラム

皆さんはどのようなツールを使ってWebサイトやWebサービスの情報設計を行なっていますか? どのようにアプリケーションが扱うコンテンツの名前を決めたり、意味を定義したり、用語を統一していますか? コンテンツの内包関係や関係性はどうでしょうか。

ALPS + ASD

ALPS + ASDはサイトからUIやデザイン要素を除いた状態でアプリケーションの情報スケルトンだけを取り出し視覚化したものです。単純な図ですが、全てのアプリケーションセマンティクスとプロトコルセマンティクスが含まれています。

遷移を含む全ての情報要素にIDが振られたこの図を使い、non-techの人も含めてサイトの情報設計を共有することができます。定義された語句はプロダクトオーナー、サーバーサイドエンジニア、クライアントサイドエンジニア、デザイナーが理解共有するのに役立ちますし、それぞれの言語で共通の語句を利用することができます14
GUIツールと違い、図もJSONから描画するのでgit管理して履歴や差分を残すことができます。誰がどの語句や繊維をいつ追加したか記録することができます。

ALPSは特定のメディアタイプに囚われない、RESTアプリケーション設計のための問題を記述する言語です。HTTPやOpenAPIといった実装の上位に位置します。この段階ではURLやHTTPステータスコード、スキーマによる制約といった実装のための制約はまだ出現していません。

ドキュメントサイトのデモを試してみてください。

ALPS Unified

設計言語を実装の詳細にブリッジするのがALPS Unifiedです。

ALPS UnifiedはALPSドキュメントを各種IDL (Interface definition language)に変換します。現在サポートしているのはOpenAPI, SDL, Proto3, AsyncAPI, WSDLです。

Amazon CDKをサポートするCDK Alps Spec Rest Apiも開発が続けられています。

弁護士ドットコムでの取り組み

現在、弁護士ドットコムでBUSINESS LAWYERS(ビジネスロイヤーズ)というサービスでALPSを使った情報設計に取り組んでいます。得られたフィードバックは後述するAOOHでALPSコミュニティに伝えALPSプロジェクトにも役立っています。

弁護士ドットコムは継続してきたビジネスとそのソフトウエア基盤がありますが、週に一度のTech Focus Day (TFD)では既存コードのリファクタリングや実験的な事でも可能な新しい取り組みを行なっています。ALPSもTFDで取り組み始めました。

ALPS Open Office Hours (AOOH)

今年の10月からAOOHという1h程度のオンラインミーティングが週一で開催されています。
参加は少人数ですが、主催の@mamundさんは多くの登壇経験や著作のある世界でも最高のAPIコンサルタントの一人です。そういった一流の方とアイデアを出し合い、議論し、プロジェクトを前に進めていくことはエキサイティングです。

私の英語はBad Englishですが、オープンソースにはもっとBad Englishが必要です。 プロジェクトにコントリビューターとして関わりたいと考え、AOOHに参加を続けています。

http://mamund.site44.com/alps/

RWABook

RESTful Web APIs は2013年に発売された本ですが、今日でも本格的なREST API (Hypermedia API)を設計するのに必要な読む価値のある良書です。リソース表現やハイパーメディアなどのWebの基礎技術を改めて紹介した後に、ドメイン固有設計や、コレクションパターン、ハイパーメディア設計を学び、REST APIの設計手法を学びます。付録のAPI Designer's Guide to the Fielding Dissertation (API設計者のためのREST論文)も読み応えがあります。

まずは目次をご覧になってください。
http://restfulwebapis.com/chapters.html

RWABook読書会について

改めて読書会をしようとしたモチベーションになったのが RESTlessnessに打ち勝つ という記事です。"ソフトウェアエンジニア産業は,成熟したRESTエコシステムを基盤として,新たなプロトコルの技術的長所を探求する手段を模索するべき" との意見に共鳴します。

読書会は弁護士ドットコム主催で RESTful WEB APIs読書会として2019年10月から開催しています。当初はオフライン開催で参加者に弁護士ドットコムからお寿司+飲み物を提供していただいていました。現在はオンラインで月1回の開催で、毎回、国内最高のRESTエキスパートの@tkawaさんにご参加いただいています。

本書は英語版しかありませんが、DeepLと@tkawaさんの助けを借り一人で読み進めるよりグッと楽しく進めてるのではないかと思います。

来年もよろしくお願いします

来年最初の1回目はこれまでの総集編を考えています。今までの一年はなんだったのかというくらいきちんとまとめてお話ししたいと考えてますので、ちょっと休んでた方も、初めての方も是非ご参加ください! 予定は運営担当の@TSUCHIYA_Naokiさんや、compassから発表されます。

明日は @happylifetaka さんの記事です。お楽しみに!

参考リンク


  1. Content TypeはHTTPヘッダーでのメディアタイプの指定する時に使われます。 

  2. MIME TypeはMedia Typeの以前の呼び方 https://www.iana.org/assignments/media-types/media-types.xhtml 

  3. Internet Assigned Numbers Authority https://www.iana.org 

  4. ロビン・ベルジョンさん (@robinberjon) W3CでHTML5の仕様策定者。 

  5. Webブラウザ、オーサリングツール、サーチエンジン 

  6. GitHub APIはこれを行っています。https://docs.github.com/en/free-pro-team@latest/rest/overview/api-previews これらのカスタムメディアタイプはIANAに登録されてもいません。 

  7. RFC6509 The 'profile' Link Relation Type https://tools.ietf.org/html/rfc6906 

  8. アプリケーションで使う語句に意味を明示的に与える事です。 

  9. 広く誤解されてますが統一インターフェイス制約はHTTPメソッドとCRUDのマッピングではありません。https://www.infoq.com/jp/articles/subbu-allamaraju-rest/ 

  10. 実際にはtypeのデフォルトはsemanticなのでtype:semanticは省略可能です。 

  11. 例えばschema.orgではPersonのプロパティにfirstNameではなくgivenNameが使われています。https://schema.org/givenName 

  12. HTMLのAタグやFORMタグでURLが与えられるHTMLがその典型です。クライアントはURLを組み立てずサーバーから示されたリンクをたどるだけです。 

  13. REST制約の中の4つの統一インターフェイス制約の1つ、アプリケーション状態のエンジンとしてのハイパーメディアでもこの用語が使われています。 HATEOAS(Hypermedia as the Engine of Application State)とも呼ばれます。 

  14. CSS、API、サーバーサイド言語やJSでの変数、クラス名、メソッド名、DBスキーマなど 

15
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
koriym
Hello BEAR.Sunday
bengo4
「専門家をもっと身近に」を理念として、人々と専門家をつなぐポータルサイト「弁護士ドットコム」「弁護士ドットコムニュース」「税理士ドットコム」を提供。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
15
Help us understand the problem. What is going on with this article?