Webアプリケーション用のAPIを開発するために、RESTとJSON-RPCのどちらかを選択しようとしています。彼らはどのように比較しますか?
アップデート2015:クライアントとサーバーの両方で理解される既存の成熟したHTTPプロトコルをAPIで利用できるため、Web/HTTPで提供されるAPIのRESTの開発と使用が簡単であることがわかりました。たとえば、応答コード、ヘッダー、クエリ、投稿本文、キャッシュ、その他の多くの機能を、追加の作業や設定なしでAPIで使用できます。
RPC の根本的な問題はカップリングです。RPC クライアントは、いくつかの方法でサービスの実装と密接に結合されるようになり、クライアントを壊さずにサービスの実装を変更することは非常に難しくなります。
一方、REST スタイルでは、コントロール情報を表現 (HTTP ヘッダー + 表現) に含めることで、クライアントを誘導するのは非常に簡単です。例えば:
REST 側には、さらに多くの違いと利点があります。
この問題を詳細に調査した結果、純粋な REST では制限が多すぎて、RPC が最適であると判断しました。ただし、私のアプリのほとんどは CRUD アプリですが。REST に固執する場合、最終的には、特定の目的のために別の必要なメソッドを API に簡単に追加する方法を知り、頭を悩ませることになります。多くの場合、REST でこれを行う唯一の方法は、REST 用に別のコントローラーを作成することです。これにより、プログラムが過度に複雑になる可能性があります。
RPC を選択した場合の唯一の違いは、動詞を URI の一部として明示的に指定していることです。これは明確で、一貫性があり、バグが少なく、まったく問題ありません。特に、単純な CRUD をはるかに超えるアプリを作成する場合は、RPC が唯一の方法です。RESTful 純粋主義者には別の問題があります。HTTP POST、GET、PUT、DELETE は HTTP で明確な意味を持ち、REST によって他の意味に転覆されました。これは、ほとんどの場合に適合するためですが、常にではありません。
プログラミングでは、1 つのことを 2 つの意味に使用しようとすると、いつか出くわし、あなたを苦しめるだろうということをずっと前に知っていました。POST を使用すると、メソッドで必要なデータを自由に送受信できるため、ほぼすべてのアクションに POST を使用できるようにしたいと考えています。全世界を CRUD に収めることはできません。
まず、HTTP-RESTは「RepresentationalStateTransfer」アーキテクチャです。これは多くの興味深いことを意味します:
次に、HTTP-RESTはHTTPに完全に準拠しているため(前の部分の「安全」と「べき等」を参照)、HTTPライブラリ(既存のすべての言語に存在する)とHTTPリバースプロキシを再利用できます。高度な機能(キャッシュ、認証、圧縮、リダイレクト、書き換え、ロギングなど)をゼロ行のコードで実装する機能。
最後になりましたが、HTTP 1.1の設計者(およびRESTの発明者)によると、RPCプロトコルとしてHTTPを使用することは大きなエラーです:http://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation。 htm#sec_6_5_2
IMO、重要なポイントは、アクションとリソースの向きです。REST はリソース指向であり、CRUD 操作に適しています。その既知のセマンティクスを考えると、最初のユーザーにはある程度の予測可能性が提供されますが、メソッドまたは手順から実装されると、リソース中心の世界への人為的な翻訳を提供する必要があります。一方、RPC は、CRUD 可能なリソース セットではなく、サービスを公開するアクション指向の API に完全に適しています。
REST の方が人気があることは間違いありません。API をサードパーティに公開したい場合、これは間違いなくいくつかのポイントを追加します。
そうでない場合 (たとえば、SPA で AJAX フロントエンドを作成する場合)、私の選択は RPC です。特に JSON-RPC は記述言語として JSON スキーマと組み合わされ、ユースケースに応じて HTTP または Websockets を介して転送されます。
JSON-RPCは、同期または非同期 RPC で使用される要求と応答の JSON ペイロードを定義するシンプルで洗練された仕様です。
JSON スキーマは、JSON データを記述することを目的とした JSON ベースの形式を定義するドラフト仕様です。JSON スキーマを使用してサービスの入力メッセージと出力メッセージを記述することにより、使いやすさを損なうことなくメッセージ構造を任意に複雑にすることができ、サービス統合を自動化できます。
トランスポート プロトコル (HTTP と Websockets) の選択は、HTTP 機能 (キャッシング、再検証、安全性、冪等性、コンテンツ タイプ、マルチパートなど) が必要かどうか、またはアプリケーションが交換する必要があるかどうかによって最も重要になります。高頻度のメッセージ。
これまでは、この問題に関する私の個人的な意見に過ぎませんでしたが、これらの行を読んでいる Java 開発者にとって本当に役立つものになりました。私が昨年取り組んできたフレームワークは、あなたが疑問に思っているのと同じ質問から生まれました。 :
ここでライブデモを見ることができ、機能テスト用の組み込みリポジトリブラウザー (JSON Schema に感謝) と一連のサンプルサービスを示しています。
それが仲間に役立つことを願っています!
ナチョ
私は過去に REST の大ファンでした。REST には紙の上では RPC よりも多くの利点があります。さまざまな Content-Types、キャッシュ、HTTP ステータス コードの再利用をクライアントに提示できます。また、API を介してクライアントをガイドできます。また、ほとんど自明でない場合は API にドキュメントを埋め込むことができます。
しかし、私の経験では、実際にはこれではうまくいきません。代わりに、すべてを正しく行うために多くの不必要な作業を行うことになります。また、HTTP ステータス コードはドメイン ロジックに正確にマップされないことが多く、コンテキストでそれらを使用することは少し強制されているように感じることがよくあります。しかし、私の意見では、REST の最悪の点は、リソースとそれらが可能にする対話の設計に多くの時間を費やすことです。また、API にいくつかの大きな追加を行うときはいつでも、新しい機能を追加するための優れたソリューションを見つけられることを願っていますが、まだ窮地に陥っていません。
ほとんどの場合、API を一連のリモート プロシージャ コールとしてモデル化する方法について、完全に明確で明白なアイデアをすでに持っているため、これは時間の無駄のように感じることがよくあります。そして、REST の制約内で問題をモデル化するためにこのすべての努力を行った場合、次の問題はそれをクライアントから呼び出す方法ですか? 私たちのプログラムはプロシージャーの呼び出しに基づいているため、優れた RPC クライアント ライブラリを構築するのは簡単です。優れた REST クライアント ライブラリを構築するのはそれほど難しくありません。ほとんどの場合、サーバー上の REST API からクライアントの一連のプロシージャーにマップし直すだけです。図書館。
このため、今日の私にとって RPC はよりシンプルで自然なものに感じられます。私が本当に欠けているのは、自己記述的で相互運用可能な RPC サービスを簡単に作成できる一貫したフレームワークです。したがって、RPC を自分で簡単にする新しい方法を実験するために、自分のプロジェクトを作成しました。
モデルと GET/POST/PUT/DELETE パターンのみでサービスが正常に動作する場合は、純粋な REST を使用してください。
HTTP はもともとステートレス アプリケーション向けに設計されていることに同意します。
しかし、Websocket (多くの場合、ステートフルであることを意味します) を使用したい最新のより複雑な (!) リアルタイム (Web) アプリケーションの場合、両方を使用しないのはなぜでしょうか? JSON-RPC over Websockets は非常に軽いため、次の利点があります。
サーバー側 API のみを設計しているため、REST モデルの定義から始めて、後で必要に応じて JSON-RPC サポートを追加し、RPC 呼び出しの数を最小限に抑えます。
(そして括弧の使いすぎでごめんなさい)
いつものように、それは依存すると思います...
REST には、広く一般に支持されているという大きな利点があります。これは、多くのツールと書籍を意味します。さまざまな組織の多数のコンシューマーが使用する API を作成する必要がある場合、それを使用する理由は 1 つだけです。人気があるからです。コマンドを URL/動詞/応答にマップする方法がまったく異なる方法が多すぎるため、プロトコルとしてはもちろん完全な失敗です。
したがって、バックエンドと通信する必要がある単一ページの Web アプリを作成する場合、REST は複雑すぎると思います。この状況では、アプリと API が一緒に進化できるため、長期的な互換性について心配する必要はありません。
私は一度、単一ページの Web アプリ用に REST を使い始めたことがありますが、Web アプリとサーバーの間のきめ細かいコマンドにすぐに夢中になりました。パスパラメータとしてエンコードする必要がありますか? 体内?クエリ パラメータ? ヘッダー?URL/Verb/Response の設計後、Javascript でこの混乱をコーディングし、Java でデコーダーをコーディングしてから、実際のメソッドを呼び出す必要がありました。そのためのツールはたくさんありますが、ドメイン コードで HTTP セマンティクスをまったく取得しないのは非常に厄介であり、これは非常に悪い習慣です。(凝集)
中程度の複雑なサイト用に Swagger/OpenAPI ファイルを作成してみて、そのファイル内のリモート プロシージャを記述した単一の Java インターフェイスと比較してください。複雑さの増加は驚異的です。
したがって、単一ページの Web アプリケーション用に REST から JSON-RPC に切り替えました。a私は、サーバー上で Java インターフェースをエンコードする小さなライブラリーを開発し、それをブラウザーに送りました。ブラウザーでは、これにより、各関数の promise を返すアプリケーション コードのプロキシが作成されました。
繰り返しますが、REST がその地位を占めているのは、REST が有名で十分にサポートされているからです。根底にあるステートレス リソースの哲学と階層モデルを認識することも重要です。ただし、これらの原則は RPC モデルでも簡単に使用できます。JSON RPC は HTTP 上で動作するため、この分野では REST と同じ利点があります。違いは、これらの原則にうまく対応していないこれらの関数に出くわすことが避けられない場合でも、多くの不必要な作業を強いられることはないということです。
REST と JSON-RPC のどちらかを選んで、よりわかりやすい Web アプリケーションの API を開発した方がよいでしょう。JSON-RPC は、メソッド呼び出しと通信へのマッピングが容易に理解できるため、優先されます。
最適なアプローチの選択は、制約または主要な目的によって異なります。たとえば、パフォーマンスが主要な特性である限り、JSON-RPC (たとえば、ハイ パフォーマンス コンピューティング) を使用することをお勧めします。ただし、他の人が推測できる汎用インターフェイスを提供するために不可知論的であることを主な目的とする場合は、REST を使用することをお勧めします。両方の目標を達成する必要がある場合は、両方のプロトコルを含めることをお勧めします。
実際に REST を JSON-RPC から分離するのは、REST が慎重に考え抜かれた一連の制約をたどり、アーキテクチャの柔軟性を確認していることです。制約は、クライアントとサーバーが互いに独立して成長できること (クライアントのアプリケーションを台無しにすることなく変更を行うことができる)、呼び出しがステートレスであること (状態はハイパーメディアと見なされる)、均一であることを保証します。インタラクション用のインターフェイスが提供され、API は階層化されたシステム上で進化しています (Hall、2010 年)。JSON-RPC は高速で簡単に使用できますが、前述のようにリソースとパラメーターは密接に結合されており、REST は疎結合のリソース (api /users) を HTTP で使用します。REST API は、GET、PUT、POST、DELETE、PATCH などのいくつかの HTTP メソッドに依存しています。
JSON (JavaScript Object Notation と呼ばれる) は軽量のデータ交換フォーマットであり、人間が読み書きするのは簡単です。マシンが解析して生成するのは簡単です。JSON は、完全に言語に依存しないテキスト形式ですが、C#、C、C++、Java、Perl、JavaScript、Python などの多数の言語で構成される言語ファミリーのプログラマーが熟知している規則を実践しています。このような特性により、JSON は完全なデータ交換言語となり、選択するのに適した選択肢となります。
リソースを要求する場合は、RESTful API の方が設計上優れています。多くのパラメーターと単純な CRUD 以外の複雑なメソッドを使用して複雑なデータを要求する場合は、RPC が適切な方法です。
RPC プロトコルに vdata を使用します: http://vdata.dekuan.org/
1、PHPとJavaScriptはどちらもOKです。2, クロスオリジン リソース共有 (CORS) 呼び出しは引き続き問題ありません。