世界を動かす技術を、日本語で。

ほとんどのRESTful APIは実際にはRESTfulではない

概要

  • RESTは Roy Fieldingの論文 で提唱された アーキテクチャスタイル
  • RESTの本質は スケーラビリティ・シンプルさ・適応性 の追求
  • HATEOAS(ハイパーメディア駆動) がRESTの重要な原則
  • リソースは URIで一意に識別される抽象概念
  • RESTful APIと呼ぶには 厳格なルールと制約 が存在

RESTの本質とFielding論文の要点

  • RESTは “Representational State Transfer” の略称、 ネットワーク型システム設計 のためのスタイル
  • “Architectural Styles and the Design of Network-based Software Architectures” (2000年、Roy T. Fielding著)で初めて体系化
  • RESTは スケーラビリティ、パフォーマンス、保守性 を重視した設計指針
  • Webサービス設計 における 分散システムの成功要因 としてREST原則を紹介
  • RESTは HTTPメソッドやCRUD に限定されず、 原則と制約 の集合体

RESTの誤解と正しい理解

  • REST=CRUDRESTful APIは動詞禁止 などの俗説は誤り

  • RESTの本質は ハイパーメディア(HATEOAS) による状態遷移の駆動

  • “REST APIs must be hypertext-driven.” (Fielding, 2008年)という明確な主張

  • ハイパーメディア制御 は、リソース表現内に次のアクションを案内するリンクや操作情報を埋め込む仕組み

  • クライアントとサーバーの 疎結合進化可能性 の確保が目的

    • 例:
      {
        "orderId": 123,
        "_links": {
          "self": { "href": "/orders/123" },
          "cancel": { "href": "/orders/123/cancel", "method": "POST" }
        }
      }
      

RESTにおける「リソース」とは

  • RESTにおけるリソースは URIで識別可能なあらゆる情報単位
  • 物理オブジェクト、概念、ドキュメント、サービス、抽象的なもの までも含む
  • リソースは サーバー上のエンティティそのものではなく、抽象的なマッピング
  • RFC 3986 も「リソースはURIで識別できるすべてのもの」と定義
  • 例:電子文書、画像、サービス、人物、企業、数値、関係タイプなど

FieldingによるRESTful APIの条件

  • HTTPベースなら何でもREST API という誤解をFielding自身が批判

  • RESTful APIと呼ぶための 6つのルール を提示

    1. 単一プロトコル依存の排除
      • URIによる識別は HTTP固有でなく、URI全般 で成り立つべき
    2. プロトコルの拡張・改変の禁止
      • HTTP標準の範囲内で動作、 独自拡張や仕様破壊は禁止
    3. URI設計よりメディアタイプ重視
      • リソース表現のフォーマットやリンク設計 に注力
      • URIやエンドポイントの構造記述は最小限に
    4. 固定リソース名・階層の否定
      • クライアントがURI構造を前提にしない設計
      • URI生成方法をサーバーが表現内で動的に指示
    5. 型付きリソースの排除
      • クライアントにとって重要なのは 表現のメディアタイプと標準化された関係名 のみ
    6. 初期URI以外の事前知識不要
      • 初期URIと標準メディアタイプ のみで利用開始
      • 以降の状態遷移はすべて サーバー提供のリンクや操作 によって誘導

REST設計ルールの解釈

  • 1. プロトコル依存の排除

    • URIは 資源の識別アクセス手段 を分離
    • URLはURIの一種 であり、API設計は HTTP固有に依存しない べき
  • 2. プロトコル変更の禁止

    • HTTP標準の厳守
    • 標準の曖昧部分は明確化してもよいが、 新たな意味付けや破壊的変更は禁止
  • 3. URIよりメディアタイプ設計

    • APIは データ表現形式(例:JSON, HTML)とリンク設計 に注力

    • URIの構造や操作のドキュメント化 よりも、 表現内のリンクや操作情報 の設計が重要

      • 例:
        {
          "name": "John Doe",
          "status": "inactive",
          "_links": { ... }
        }
        
  • 4. 固定リソース名・階層の否定

    • サーバー主導のURI生成 (HTMLフォームやURIテンプレートなど)
  • 5. 型付きリソースの排除

    • クライアントは 表現のメディアタイプとリンク関係名 のみを認識
  • 6. 初期URI以外の事前知識不要

    • 初期エントリーポイントURIと標準メディアタイプ だけで利用開始
    • 以降の状態遷移は サーバーからのリンク・操作案内 に従う

REST設計のまとめ

  • RESTは 単なるHTTP API設計手法ではなく、厳密なアーキテクチャスタイル
  • HATEOAS の実装がRESTful APIの鍵
  • URIで識別できるものはすべてリソース
  • メディアタイプ設計とハイパーメディア制御 に注力
  • 「RESTful API」と呼ぶには厳格な条件 があることを理解する必要

Hackerたちの意見

UIデザイナーは、ページの見た目を細かくコントロールしたいんだよね。例えば、リソースに対してできるアクションの中には大きなボタンで表示されるものもあれば、メニューに隠れてたり、UIに全く表示されないものもある。リソースでどんなアクションが可能かを全く知らないクライアントアプリケーションが、APIのレスポンスに基づいて動的に表示するだけだと、全部同じに見えちゃうんだよね。だから、この記事で説明されているRESTful APIは、フロントエンドUIを実装するという最も一般的なWeb APIの使い方にはあまり役立たないんだ。

「RESTful API」に関する俺の経験は、UIとはほとんど関係ない。UIだけが気になるなら、なんでAPIなんて必要なの?それならDWRみたいなサーバードリブンのクソに戻った方がいいんじゃない?

これは多くのレベルで間違ってる。 1. UXデザイナーは、製品の発見からローンチ後のサポート(UX仮説の検証)まで、ソフトウェア開発ライフサイクルのすべての段階で活動している。彼らはコントロールを行使するわけではなく、チームの一員として制約の中で働いている。UI内の特定のアクションの位置やそれをトリガーするインタラクションは、そのアクションの可用性とは無関係だ。可用性は状態によって定義される。状態が特定のアクションを制限する場合、UXはそれを反映する必要がある。 2. アーキテクチャの観点から見ると、状態チェックの動作をカプセル化すれば、次のように動作する: "if (state === something)" と "if (resource.links["action"] !== null)"。後者のアプローチの方がずっと良い。なぜなら、ほとんどの場合、状態を変更するアクションはサーバーでの検証を必要とし、そのロジックを一度(サーバー上で)だけ実装すればいいからだ。私はしばらくHATEOASアプリケーションを開発していて、HAL4Jライブラリを維持しているけど、このアプローチにはいくつかの複雑さがある。でも、UIデザインが問題の本質ではないことは確かだよ。

こういうAPIデザインが役立つのは、ユーザーがエージェント(例えばブラウザとか)を使ってAPIをナビゲートし、メディアタイプやリンクの名前に基づいて異なるレスポンスとやり取りできる場合だね。ほとんどのWeb APIはこの使い方を考慮して設計されてない。ユーザーに提示したい内容がもっと具体的なWebアプリをサポートするために設計されているんだ。これは意図的で価値のあることだよ。アプリのクリエイターは、自分のアプリの目標を達成するためにプレゼンテーションをコントロールできる必要があるからね。REST APIデザインは、ユーザーがAPIが提供するリソースとのやり取りをどうするかをコントロールすべきなケースに向いてる。REST APIデザインを使うべき例としては、- 法律コード、天気予報、不動産記録などの公にアクセス可能な情報のための政府ポータル - フォーム提出やその他のやり取りのための政府ポータル - WikipediaやOpenStreetmapのようなオープンデータイニシアティブ これらの例を考えると、「REST」の意味を厳格に守るのは学問的な人たちから来てるのが分かるし、定義に反対する人たちは特定のユーザー体験を作ろうとしているアプリ開発者が多い。解決策は簡単だよ:本当にRESTでない限り、RESTとは呼ばないこと。

法律コード、天気予報、不動産記録などの公にアクセス可能な情報のための政府ポータル そうそう、ちゃんと作られてるとすごくいいよね。 https://www.weather.gov/documentation/services-web-api

その通り、純粋なRESTはかなり学問的だよね。オープンデータやビッグデータに関わってきたけど、現実的なパフォーマンスやアプリアーキテクチャの設計にはいつも苦労してる。明白でないものについては、単純なイエス/ノーではなく、RESTの色合いがあると思う。学者たちも、いつかは実際に適用できる「アプリケーション」を作らなきゃいけないからね。

この種のAPIデザインが役立つのは、エージェント(例えばブラウザやそれに似たもの)を持つユーザーがいて、APIをナビゲートして、メディアタイプやリンクの名前に基づいて異なるレスポンスとやり取りできるときだよね。面白いことに、これってHTMLを完璧に説明してる。リンクが他のドキュメントに繋がってるドキュメントがあって、ユーザーはリンクの名前に基づいてナビゲートできる。ユーザーのために設計されてるなら、それはユーザーインターフェースって呼ばれるし、アプリケーションプログラミングのために設計されてるなら、それはアプリケーションプログラミングインターフェースって呼ばれる。だからHATEOASはちょっとバカバカしいと思う。APIはユーザーが直接使うべきだって思わせてるけど、もうそれはあるんだよね、UIって呼ばれてる。

この種のAPIデザインが役立つのは、エージェント(例えば、ブラウザやそれに類似したもの)を持つユーザーがAPIをナビゲートし、メディアタイプやリンクの名前に基づいて異なるレスポンスと対話できるときです。 > ほとんどのウェブAPIはこのユースケースを念頭に置いて設計されていません。APIがAIの消費をサポートするようになると、これが変わるのかな?発見可能性はAIにとって非常に重要で、ウェブアプリ開発者よりもずっと重要です。MCPはツールの発見可能性がどれほど強力であるかを示しています。HATEOSは、APIの消費に同様の利点をもたらすかもしれません。

この種のAPIデザインが役立つのは、エージェント(例えば、ブラウザやそれに類似したもの)を持つユーザーがAPIをナビゲートして、メディアタイプやリンクの名前に基づいて異なるレスポンスと対話できるときだ。ウェブページでないクライアントをプログラミングしているときにも役立つ!何かをGETして、返された表現のフィールドやパスを参照して、新しいURIを構築して、操作を実行する、みたいな感じ。ディレクトリやデータベースアプリケーションを考えてみて。RESTfulでHATEOASなAPIを定義して、それ用のシングルページウェブアプリケーションを作ったり、好みに応じて非SPAを作ったり、同じことに対してライブラリやコマンドラインインターフェースも書ける。すべて、上で説明したような似たコードを使ってね。それって結構すごいことだよ。非SPAの場合は、純粋なHTMLを使って「返された表現のフィールドを参照している」と考えなくてもいいけど、ユーザーとユーザーエージェントはそれをやってるんだ。

ここでの細かいことには同情するけど、Fieldingの論文は面白かった。でも、これは負け戦だよ。「REST API」を見ると、以下のことが安全に想定できる: - APIはJSONを返す - CRUDアクションはPOST/GET/PUT/DELETEにマッピングされている - チームは正しいステータスコードについて常に議論していて、少なくともいくつかはHTTP仕様に反して使われている - リストエンドポイントが複雑なフィルターをサポートするためにPOSTに変更された可能性が高い こういうのは、アジャイルやCI、DevOpsと同じで、元の定義にこだわるか、意味の拡散に従って一般的に理解されている用語を使うかのどちらかだね。

チームは正しいステータスコードについていつも議論してて、少なくともいくつかはHTTP仕様に反して使われてる。 ここでクスッときた。ほんとその通り!

そうだね。個人的には、みんなもう少し自分たちを超えて、君が言ってることが「REST API」の本当の、正しい、現代的な意味だってことに同意すべきだと思う。

CRUDアクションはPOST/GET/PUT/DELETEにマッピングされてると安全に仮定できる。 それについては完全には確信がないけど、PUTとPATCHについて彼らがどう決めたかを確認する必要があると思う。

みんなに、論文に従って本当にRESTを意味してるのか聞くと、私はただ流すのを拒む一人なんだ。理由は、一般的に使われているこの用語が実際には何も意味しないし、役に立たないから。だから「結局、単なるウェブAPIのことを言ってるんだよね、わかった」と言って、次に進むことにしてる。重要なのは、そういうウェブAPIごとの特異性を理解する必要があるってこと。

  • CRUDアクションはPOST/GET/PUT/DELETEにマッピングされる その他の三つには同意するけど、更新や削除、時には読み取り操作までPOSTの背後にある「REST API」を見たことが多すぎる。「SOAPスタイルのREST」って呼んでる。

HTTP/JSON APIも使えるけど、これがRESTの意味だと思っていいよ。XMLベースのものに戻りたい気持ちになる。ちゃんとした基準があって、基準に従わないものにはライブラリが厳しく対応してたから。HTTP/JSON APIはしばしば手作りで、手で読まれることが多い。NIH症候群が蔓延してるのは、シンプルでわかりやすいと見なされてるから。まるで「仕様はいらない、レスポンスを自分で見ればいいでしょ?」って感じ。少なくとも2012年頃はそんな状態だった。今はOpenAPI仕様を使ってるけど、しばしば不完全で、手作りの場合(その場合、埋めるべきことを知らない人が多い)や生成された場合(その場合、生成器には制限があって、カスタムコメントのサポートがあったりなかったりする)に関わらず。

ここでの細かいことに同情するし、フィールドの論文は面白いと思ったけど、これは失われた戦いだ。なぜ人々はこれを戦いだと考えることに強いられるのか?私の見解では、RESTの概念は役に立つけど、HATEOASの詳細は実際には価値がなく、解決する問題よりも多くの問題を生んでしまう。これはリチャードソンの成熟度モデル[1]に沿ったもので、RESTの頂点にはすべてのHATEOASの装飾が含まれている。HATEOASなしのRESTはRESTとして分類されるべきか?なぜダメなの?要するに、すべての要件を満たしているが一つだけ満たしていないアーキテクチャスタイルを区別する強い理由は何?HATEOASが実質的に無関係で、ほとんどのRESTful APIがそれを実装していない場合、この細かいことに意味はあるの?この細かいことに何の価値があるの?モンティ・パイソンのスキットのように論文を引用することに価値はあるの? [1] https://en.wikipedia.org/wiki/Richardson_Maturity_Model

自分の結論がすごく嫌なんだけど、限られた自由の観点から見ると、もし全部そうなるなら… > チームは正しいステータスコードについてずっと議論していて、少なくともいくつかはHTTP仕様に反して使われてる。だから、まずはレスポンスのための標準的な枠組みを作って、エラーをエンコードしてステータスコードのことは忘れた方がいい。エラー状態を生成するのは、未処理の例外が500にマッピングされるときだけ。それが人々の意見が分かれても生き残るデザインなんだ。 > エンドポイントが複雑なフィルターをサポートするためにPOSTに変更された可能性が高いから、最初からリストがGETとPOSTの両方をサポートするように標準化した方がいい。ついでに、URLとボディパラメータの両方でクエリを受け入れるようにしよう。

フィールドは、知的に一貫性がなく、ほとんど間違っているからこそ、本当の戦いに勝った。21世紀の「悪い方が良い」ってやつだ。RPCシステムは、使いにくいことで有名で、せいぜいわずかに成功しただけ。Sun RPC、RMI、DCOM、CORBA、XML-RPC、SOAP、プロトコルバッファなどを見てみて。人々は「RPCじゃない」って言うけど、実際には常にこんな感じの関数を書いてるんだ。const getItem = async (itemId) => { ... } これはGET /item/{item_id}を実行して、バックエンドにはItem getItem(String itemId) { ... }みたいな関数があって、URLをアイテムコールにマッピングする方法を説明するアノテーションがある。だから、これはRPCだけど、知的に一貫性があっても使いにくい複雑なシステムの代わりに、もっと手動的だけど余裕があって、開発者がコントロールを感じられるシステムがある。問題の80%は、人々がISO 8601の日付を使おうとしないことだ。

13年前に初めてHTTPベースのAPIを作ってた時、真のRESTについての多くのコメントを見て、まずRESTが本当に何であるべきかを学ぶことにしたんだ。Fieldingの論文を隅から隅まで読んで、O'ReillyのRESTful Web Services Cookbookも読んで、それからDjangoのイディオムを回避してREST APIを提供することにした。これはちょっとカゴカルト的な考え方だったと思う。RESTが自分のサービスにどんな利益をもたらすのかを本当に理解してなかったんだ。数年後、いくつかのHTTP APIを経て、これらのサービスの場合、利益はなかったことに気づいた。自己発見可能で、汎用クライアントで動作するAPIのビジョンは、ほとんどの場合実用的じゃないと思う。AWSのダッシュボードは多くのサービスを持っていて、サービス固有のロジックなしでこれらのサービスを扱うための汎用UIコードがあるかもしれないけど、そこまで疑ってる。Fieldingの論文は自己発見可能なAPIを構築するための完全なレシピを提供していない。アーキテクチャではあるけど、クライアントがエンドポイントを本当に発見し、これらのエンドポイントが何をしているのかを判断する方法の詳細は論文から省かれている。真に発見可能なAPIを作るには、エンドポイントの発見、操作の説明、ヘルプメッセージなどのプロトコルを指定する必要がある。その後、あなたの仕様を理解するクライアントが必要だから、それは本当に汎用クライアントではない。もしあなたのサービスだけがこのクライアントを実装しているなら、RESTでないサービスが実装しているのと同じ解決策にたどり着くために多くの余分な努力をしたことになる。サービスがAPIを提供し、APIと連携するためのJSコード(またはAPIと連携するコマンドラインクライアント)を提供するけど、クライアントコードの再利用は全くないんだ。良いUXはRESTの目標とは相容れないと思う。ユーザーの視点から見ると、アプリ固有のコードは、エンドポイントを発見してどのアプリでもUIを提供できる汎用コードよりも良いUXを提供できる。もちろん、UI要素は標準化されて、いくつかの言語で説明されることができる(XULを覚えてる?)、だからUIはアプリの要件に適応できる。でも、こうした標準化の最も柔軟な方法は、UIを構築するためのJavaScriptのような言語を提供することだと思う。

君の言う通りだと思う。APIにはたくさんの側面があって、説明するのが難しいよね。APIユーザーは典型的なレイテンシーの範囲、どのエラーコードがリトライ可能か、アクションがアトミックかアイデポテントかを知る必要がある。HATEOASはこれらのことを何も提供してくれないから、完璧なRESTの実装はほとんどの問題には必要ないことが多い。RESTがもたらしたのは、業界全体で通じる共通語みたいなもの。基本的には、名詞や動詞をHTTPの動詞やURLにマッピングする基本的な理解だよね。ユーザーは基本的なHTTPレスポンスコードを使えるし、まだまだデザインや微妙な部分がたくさんある。技術的には許可されているけど、典型的なロードバランサーで壊れちゃうかもしれないことをやることが本当にできるの?(特定のエラーコードを返すボディを返すとか)返す500は全てのケースでリトライ可能なの?どんなバックオフの挙動が好ましいの?

元々のRESTだけじゃなくて、業界が再解釈した弱いRESTも、ほとんどメリットがないことが多いです。リソースを削除するのに、DELETE HTTPメソッドを使わなきゃいけないって、そんなに重要ですか?

真に発見可能なAPIを作るには、エンドポイントの発見、操作の説明、ヘルプメッセージなどのプロトコルを指定する必要があります。次に、あなたの仕様を理解できるクライアントが必要ですから、実際には一般的なクライアントではありません。一般的なクライアントはハイパーメディアを理解すれば、あなたのAPIを発見できます。APIがそのスタートエンドポイントからハイパーメディアを返し、他のすべてのエンドポイントがそのスタートポイントから遷移的にリンクされている限り。これをお聞きしたいのですが、もしあなたの好きなOO言語でオブジェクトXを与えたら、その言語のリフレクション機能を使って、Xから遷移的に到達可能なすべてのオブジェクトのプロパティや、XおよびXから遷移的に到達可能なすべてのオブジェクトで呼び出せるメソッドを発見できますか?パラメータの型が主に標準化されたオブジェクトであるか、標準化されたオブジェクトを受け入れるコンストラクタを持つ場合、これらのメソッドの多くを呼び出すことはできませんか?これがHATEOASによる発見可能性です。真のRESTはリフレクション機能を持つオブジェクトモデルをエクスポートしていると見なすことができます。あなたのAPIに慣れたクライアントは、ハイパーメディアを使って既知のプロパティやメソッドにアクセスし、一般的なクライアントはリフレクションを使って同じことができます。

フィールドの論文は、自己発見可能なAPIを構築するための完全なレシピを提供していない。でも、実際にはそうなんだ。HTTPサーバーは、ブラウザからのリクエストに対してHTTPレスポンスを返す。リクエストはHTMLウェブページで、ユーザーに表示されるときには、すべての発見可能なAPIがクリック可能なリンクとして見える。ようこそ、ワールドワイドウェブへ。

ブラウザは、私たちが毎日使うUXを提供する「一般的なコード」なんだ。RESTは、サーバーからのレスポンスの一部としてコードを含むことを許可しているけど、明らかにセキュリティの問題がある。でも、ブラウザ(や基準)はその多くを対処してきたよ。 https://ics.uci.edu/~fielding/pubs/dissertation/net_arch_sty...

APIが自己発見可能で、汎用クライアントと連携するというビジョンは、ほとんどの場合実現不可能だよね。 フィールドの論文は、自己発見可能なAPIを構築するための完全なレシピを提供していないし、アーキテクチャについては触れているけど、クライアントがエンドポイントをどうやって発見し、何をしているのかを判断するかの詳細は省かれてる。 真に発見可能なAPIを作るには、エンドポイントの発見、操作の説明、ヘルプメッセージなどのプロトコルを指定する必要があるんだ。それに、あなたの仕様を理解するクライアントが必要だから、実際には汎用クライアントじゃないよね。 君が言ったことは、私がRESTについて考えていたことをより上手く表現してくれた。 本当のRESTクライアントの実装は、単純に不可能なんだ。どのURLが何をするのか、クライアントは知っておく必要がある。 もし突然新しいアクション(例えば /cansofspam/123/frobnicate)を追加したら、クライアントはそれにどう対処するか分からない。 クライアントはfrobnication機能を追加するために更新される必要があるし、そうでなければ無視するしかない。せいぜい「Frobnicate」ボタンを表示するくらいだね。 これが、誰もフィールドの論文に実際に準拠したRESTサーバーやクライアントを実装していない理由なんだ。 APIを本当に自己発見できるクライアントを持つのは現実的じゃないし、どのAPIを期待するかを知るように書かれていないと無理なんだよ。

HATEOASのミームがなんでまだ生き残ってるのか全然理解できない。誰か使ってるの?どこかで?自動発見できるAPIを使える魔法のクライアントってどんなの?それに、なんでそのクライアントは話してるサーバーのことを何も知らないの?

ODataは使われてないと思うけど、あれはちゃんとした標準で、クリアするのも簡単だよね。HATEOASは人気のある標準からも恩恵を受けてないし、それが原因でもあり結果でもある。

HTMLを表示するためにブラウザを使ってる人は、HATEOASを使ってるってことに気づいてる?SPAが当てはまるかどうかは議論の余地があるけど、サーバーでレンダリングされたり静的なサイトは確実にHATEOASを使ってる。ポイントは、クライアントがサーバーについて全くの無知である必要はないけど、完全に知識を持っている必要もないってこと。私たちはそのアプローチに慣れてきたけど、ほとんどの人がフロントエンドがバックエンドの動作を正確に知っているような密結合のアプリを作ってきたから、ウェブサイトやウェブアプリを作る方法はそれだけじゃないんだよね。

https://htmx.org/ が一番近い試みかも?

HATEOASのミームがなぜ死なないのか理解できない。 > 誰か使ってる?どこかで?私の記憶では、ACME(Let’s Encryptで使われるプロトコル)はHATEOASプロトコルだ。もしそうなら(RFC 8555をざっと見るとそうかもしれない)、HTTPSを提供しているほとんどの人が使ってることになる。HTTPは、本来の意図通りに使われると、実際にはHATEOASプロトコルだと言える。 > 自動発見可能なAPIを利用できる魔法のクライアントってどんなの? そして、なぜこのクライアントは話しているサーバーについて前もって知識がないの?LLMはこれが得意みたい。自動発見って言っても、いろいろな意味があるからね。次のリソースの自動発見を可能にするリンクが次に続く(それが何を意味するかは別として);それはクライアントが「次」が実際に何を意味するかについての前提知識を持っていることを前提にしてる。

そうですね。あなたはこのコメントを書くためにそれを使いました。私はこの返信を書くために使っています。自動発見可能なAPIを利用できる魔法のクライアントは「ウェブブラウザ」と呼ばれています。今まさにあなたが使っているものです。

エンタープライズグレードのビデオ監視システムで使ったんだけど、すごく良かった。APIレベルでバージョン管理と権限の問題を基本的に解決してくれた。他のRFCも適用できるところは活用したよ。一番の問題は、人々が「楽にする」ためにモデルを曲げようとすることだったけど、実際にはそれが逆に難しくしてた。二番目の問題は、JSONがそのままではハイパーテキストフォーマットじゃないこと。これがapplication/jsonをHATEOASに適さなくして、ハイパーテキストのセマンティクスを強制するのはいつもごちゃごちゃしてる感じがした。

この話題が出るときに見落とされがちなのは、バックエンドAPIが誰のためにあるのかってこと。RESTやHATEOASは、消費者がバックエンドを直接所有していない第三者を想定しているときに有益なんだ。よくある例は、普通のHTMLページで、そのAPIのエンドユーザーはブラウザを使っている人。MCPは最近の例で、そのプロトコルは、エージェントが自分の持っていないAPIと話すために必要で、JSON RPC APIの海の中で発見性や解釈性のための解決策が必要だから。APIの消費者がそのバックエンド専用に書かれたフロントエンドアプリの場合、RESTの利点はコストを上回ることがほとんどない。より一般的で、より良く文書化された、仕様が明確なAPIを設計するには労力がかかるからね。私は本番環境でtRPCのようなツールを使うのは好きじゃないけど、プロトタイピングにはすごく役立つ。アプリの両端を作ってるから、関心の分離を無視する方が早いんだ。編集:タイプミス

*HATEOAS

すごく同意します!もっと深い意味があると思います!

これはRESTの概念についての非常に良い詳細なレビューですね。著者に拍手を送りたいです。もう一つ付け加えたいのは、RESTful/HATEOASパターン(本来の意味で)を使うには、それに対応したクライアントが必要で、そうしないと効果が薄いってことです。

それが解決しようとしている核心的な問題は、クライアントとサーバーの結合です。サーバーのURI構造に小さな変更を加えるだけで、複数のクライアントアプリケーションの調整(しかも痛い思いをすることが多い)を必要とするプロジェクトは数え切れないでしょう。HATEOAS主導のアプローチは、クライアントをサーバーの名前空間から切り離すことでこれを直接解決します。これが進化可能性の質に関わる問題です。これには同意できません。結局、結合の問題を別の場所に移動させるだけです。ドキュメント内でURLを見つける方法がわからないクライアントは、間違ったURL構造を仮定するクライアントと同じくらい悪いです。APIのクライアントは、そのAPIが提供するセマンティクスや、どのようにそれを提供するかを理解する必要があります。URL階層からドキュメント構造に移すことは、大きな付加価値を提供するわけではありません。特に、ほとんどすべてのサーバーAPIがハンドラーにルーティングするURLパターンで定義されている世界では、これはHATEOAS哲学に反するスタイルで考えることを明示的に促すものです。また、データフォーマットがXMLからJSONに広がることが「純粋な」REST/HATEOASに逆効果をもたらしていると思います。XMLはJSONに比べてはるかに豊かな型構造を持っていました。JSONは表面的には解析が簡単ですが、時間やハイパーリンクなどを特定するのは、これらの標準化が不足しているため、より難しいです。JSONはハイパーテキストに必要な基本概念の十分なネイティブかつ広範な表現を提供していません。 (これは反例があれば嬉しい時の一つです。元々の「ブラウザを通じて人間にハイパーテキスト文書を提示する」というユースケースを除いて、純粋なHATEOASスタイルで書かれた成功したプログラムAPIの例をもっと読みたいです。)

これが私も理解できないところです。/user/123/orders これは、/user/123をリクエストして、レスポンスボディに「orders」というリンクがあると仮定するのと、根本的にどう違うんでしょうか?

ソフトウェアアーキテクト(まだいるのかな?)やAPIを担当するシニアエンジニアには、APIの消費者についてよく考えるようにいつも勧めてる。もし唯一の消費者が自分のUIだけなら、もっと統合されたRPCスタイルを使って速くするべきだ。OpenAPIとかは忘れて、UIが必要とするデータを簡単に提供できるツールやライブラリを使おう。もし消費者が自分の組織の外にいるなら、RESTっぽいAPIだね。もし消費者が一般的で「あなたのAPIを発見」できるべきなら、RESTfulが正解。でも、もう誰も一般的なものは書かない。私たちはすでに究極のものを持ってる:ブラウザだ。

何年も前にこれを通り抜けて、新しい用語を作るべきだと決めたんじゃなかったっけ - RESTライクって。それで全部片付いたのに?