web-dev-qa-db-ja.com

JSON-RPCに対するREST

Webアプリケーション用のAPIを開発するために、RESTとJSON-RPCの間で選択しようとしています。 APIクライアントにはどちらが使いやすいですか?

Update 2015:私はRESTを開発し、Web/HTTPで提供されるAPIの使用を容易にしました。これは、クライアントとサーバーの両方で理解される既存の成熟したHTTPプロトコルを利用できるためです。 。たとえば、レスポンスコード、ヘッダー、クエリ、投稿本文、キャッシュ、およびその他の多くの機能を、追加の作業や設定なしでAPIで使用できます。

235
Ali Shakiba

RPCの基本的な問題はカップリングです。 RPCクライアントはいくつかの点でサービスの実装と密接に関連しており、クライアントを壊すことなくサービスの実装を変更することは非常に困難になります。

  • クライアントはプロシージャ名を知っている必要があります。
  • プロシージャパラメータの順序、種類、数の問題。クライアント側の実装を壊すことなくサーバー側で手続きシグネチャ(引数の数、引数の順序、引数の型など)を変更するのはそれほど簡単ではありません。
  • RPCスタイルは、手続きの終点+手続きの引数以外は何も公開しません。次にできることをクライアントが判断することは不可能です。

一方、RESTスタイルでは、コントロール情報を表現(HTTPヘッダー+表現)に含めることでクライアントをガイドするのはとても簡単です。例えば:

  • これらのURIの意味を伝えるリンクリレーションタイプで注釈を付けられたリンクを埋め込むことは可能です(そして実際には必須です)。
  • クライアント実装は、特定のプロシージャ名と引数に依存する必要はありません。代わりに、クライアントはメッセージフォーマットに依存します。これは特定のメディアフォーマット(例えばAtom、HTML、Collection + JSON、HALなど)のために既に実装されたライブラリを使用する可能性を生み出します。
  • 登録された(またはドメイン固有の)リンク関係にのみ依存している限り、クライアントを壊すことなくURIを簡単に変更することができます。
  • フォームのような構造を表現に埋め込むことは可能で、エンドユーザーが人間の場合はクライアントにこれらの説明をUI機能として公開することができます。
  • キャッシングのサポートは追加の利点です。
  • 標準化されたステータスコード

REST側には、さらに多くの違いと利点があります。

207
ioseb

私はこの問題を少し詳しく調べて、純粋なRESTはあまりにも制限が厳しく、RPCは私のほとんどのアプリがCRUDアプリであっても最良であると判断しました。 RESTに執着すると、特別な目的のために他の必要なメソッドをAPIに簡単に追加する方法を考えて、結局頭をかいていることになります。多くの場合、RESTを使用してそれを実行する唯一の方法は、そのために別のコントローラを作成することです。これは、プログラムを過度に複雑にする可能性があります。

RPCを選択した場合の唯一の違いは、動詞をURIの一部として明示的に指定していることです。これは明確で、一貫性があり、バグが少なく、本当に問題ありません。特にあなたが単純なCRUDをはるかに超えるアプリを作成した場合、RPCが唯一の方法です。私はRESTfulな純粋主義者に関して別の問題を抱えている:HTTP POST、GET、PUT、DELETEは、ほとんどすべての場合に当てはまるという理由でRESTによって他のものに転用される明確な意味を持つ。時の.

プログラミングにおいて、私はずっと前に2つのことを意味するために1つのことを使おうとすることがいつかやって来てあなたを噛むことになるだろうということを発見しました。私は、あらゆるアクションに対してPOSTを使うことができるのが好きです。なぜならそれはあなたのメソッドが必要とするようにデータを送受信する自由を提供するからです。あなたは全世界をCRUDに合わせることはできません。

156
Bruce Patin

まず、HTTP-RESTは「表現状態転送」アーキテクチャーです。これは多くの興味深いことを意味します。

  • あなたのAPIはステートレスなので設計がずっと簡単で(複雑なオートマトンでの移行を忘れるのは本当に簡単です)、そして独立したソフトウェア部品と統​​合するのも簡単です。
  • あなたは安全なメソッドとしてreadメソッドを設計するようになるでしょう。
  • あなたはべき等のようにwriteメソッドを設計するようになるでしょう。

第二に、HTTP-RESTはHTTPに完全に準拠しているので(前の部分の "safe"と "idempotent"を見てください)、HTTPライブラリー(既存のあらゆる言語に存在)とHTTPリバースプロキシを再利用することができます。ゼロ行のコードで高度な機能(キャッシュ、認証、圧縮、リダイレクト、書き換え、ロギングなど)を実装する機能。

最後に重要なことを言い忘れたが、HTTPをRPCプロトコルとして使用することは、HTTP 1.1(およびRESTの発明者)の設計者によれば大きな誤りである。 http://www.ics.uci.edu/~fielding/pubs/論文/ evaluation.htm#sec_6_5_2

28
Aurélien

あなたのサービスがモデルとGET/POST/PUT/DELETEパターンだけでうまく動くならば、純粋なRESTを使用してください。

HTTPはもともとステートレスアプリケーション用に設計されていることに同意します。

しかし、WebSocketを使用したいと思う現代的でより複雑な(!)リアルタイム(Web)アプリケーション(多くの場合ステートフル性を意味します)では、両方を使用しないでください。 Webソケット上のJSON-RPCは非常に軽いので、次のような利点があります。

  • すべてのクライアントで即時更新(モデルを更新するための独自のサーバー間RPC呼び出しを定義)
  • 複雑さを追加するのは簡単(RESTだけでEtherpadクローンを作成しよう)
  • それを正しく行えば(リアルタイム専用のRPCとしてRPCを追加するだけで)、ほとんどのものはRESTのみで使用可能です(主な機能がチャットなどの場合を除く)。

サーバー側のAPIを設計するだけなので、RESTモデルの定義から始め、必要に応じてJSON-RPCサポートを追加して、RPC呼び出しの数を最小限に抑えます。

(括弧が多用されてすみません)

17
flo

IMO、重要な点は、行動対リソース指向です。 RESTはリソース指向であり、CRUD操作に適しており、既知のセマンティクスは最初のユーザーにある程度の予測可能性を提供しますが、メソッドやプロシージャから実装するとリソース中心の世界に人為的な翻訳を提供します。一方、RPCは、CRUD対応のリソースセットではなく、サービスを公開するアクション指向のAPIに最適です。

間違いなくRESTのほうが人気があります。APIを第三者に公開したい場合は、これで間違いなくいくつかのポイントが追加されます。

そうでない場合(たとえば、SPAにAJAXフロントエンドを作成する場合)、私の選択はRPCです。特にJSON-RPCは、記述言語としてJSONスキーマと組み合わされ、ユースケースに応じてHTTPまたはWebソケットを介して転送されます。

JSON-RPC は、同期または非同期RPCで使用される要求と応答のJSONペイロードを定義するシンプルで洗練された仕様です。

JSON Schema は、JSONデータの記述を目的としたJSONベースのフォーマットを定義するドラフト仕様です。 JSONスキーマを使用してサービスの入出力メッセージを記述することで、使いやすさを犠牲にすることなくメッセージ構造を任意に複雑にすることができ、サービス統合を自動化することができます。

トランスポートプロトコル(HTTPとWebSocket)の選択はさまざまな要因によって異なりますが、HTTP機能(キャッシング、再検証、安全性、べき等性、コンテンツタイプ、マルチパートなど)が必要かどうか、またはアプリケーションを交換する必要があるかどうかが最も重要です。高いfrecuenciesでメッセージ。

これまで私の個人的な意見ですが、これらの行を読んでいるJava開発者にとって本当に役立つものです。昨年私が取り組んできたフレームワークは、あなたが今疑問に思っているのと同じ質問から生まれました。 :

http://rpc.brutusin.org

ここでライブデモを見ることができます。機能テスト用の組み込みリポジトリブラウザ(JSONスキーマに感謝します)と一連のサンプルサービスを示します。

http://demo.rpc.brutusin.org

それが仲間に役立つことを願っています!

ナチョ

16
idelvall

私は過去にRESTの大ファンでしたが、紙の上でRPCよりも多くの利点があります。クライアントにさまざまなContent-Types、キャッシング、HTTPステータスコードの再利用を提示したり、APIを介してクライアントを案内したり、とにかく自己説明的でない場合はAPIにドキュメントを埋め込むことができます。

しかし、私の経験では、実際にはこれでは間に合わず、代わりに、すべてを正しくするために不要な作業をたくさんしてきました。また、HTTPステータスコードはドメインロジックに正確に対応していないことが多く、コンテキスト内で使用すると少々手間がかかります。しかし、RESTについての最悪のことは、あなたがあなたのリソースとそれらが許す相互作用を設計するために多くの時間を費やすということです。そして、あなたがあなたのAPIにいくつかの大きな追加をするときはいつでも、あなたはあなたが新しい機能を追加するための良い解決策を見つけることを願っています、そしてあなたはすでに隅に自分自身を設計しませんでした。

ほとんどの場合、私はAPIを一連のリモートプロシージャコールとしてモデル化する方法について、すでに完全に詳細で明白な考えを持っているので、これはしばしば私にとって時間の浪費のように感じます。そして、私の問題をRESTの制約の範囲内でモデル化するための努力をすべて行った場合、次の問題はクライアントからそれを呼び出す方法です。私たちのプログラムは手続きを呼び出すことに基づいているので、良いRPCクライアントライブラリを作るのは簡単で、良いRESTクライアントライブラリを作ることはそれほど多くなく、ほとんどの場合あなたはRESTからマップしますクライアントライブラリ内の一連のプロシージャに対するサーバー上のAPI。

このため、RPCは今日の私にとってはずっとシンプルで自然な感じになります。私が本当に見逃しているのは、自己記述的で相互運用可能なRPCサービスを簡単に書くことを可能にする一貫したフレームワークです。そのため、私は自分自身でRPCをより簡単にするための新しい方法を試すために私自身のプロジェクトを作成しました。そして、おそらく誰かがそれを便利にするかもしれません: https://github.com/aheck/reflectrpc

15
ahe

Richardson成熟度モデル によると、問題はREST vs. RPCではなく、いくらのREST

この観点から、REST規格への準拠は4つのレベルに分類できます。

  • レベル0:行動とパラメータの観点から考える。この記事で説明されているように、これは基本的にJSON-RPCと同じです(この記事ではXML-RPCについて説明しますが、両方に同じ議論が当てはまります)。
  • レベル1:資源の観点から考える。リソースに関連するものはすべて同じURLに属します
  • レベル2:HTTP動詞を使う
  • レベル3:HATEOAS

REST standardの作成者によると、レベル3のサービスのみがRESTfulと呼ばれます。ただし、これはコンプライアンスの測定基準であり、品質の基準ではありません。計算を実行するリモート関数を呼び出したいだけであれば、応答に関連するハイパーメディアリンクを含めても意味がありません。HTTP動詞に基づく動作の区別もありません。そのため、そのような呼び出しは本質的にRPCに近いものになる傾向があります。ただし、コンプライアンスレベルが低いということは、必ずしもステートフルまたはカップリングが高いという意味ではありません。おそらく、REST対RPCを考える代わりに、できるだけ多くのRESTを使用するべきですが、それ以上は使用しないでください。 RESTfulなコンプライアンス標準に合うようにアプリケーションをねじらないでください。

11
blue_note

なぜJSON RPC:

REST apisの場合、必要な機能やメソッドごとにコントローラーを定義する必要があります。その結果、クライアントにアクセスしたい10のメソッドがある場合、クライアントの要求を特定のメソッドにインターフェースするために10のコントローラーを作成する必要があります。

もう1つの要因は、メソッドや機能ごとにコントローラが異なる場合でも、クライアントはPOSTまたはGETを使用することを覚えておく必要があるということです。これは事態をさらに複雑にします。それに加えて、データを送信するには、POSTが使用されている場合、リクエストのコンテンツタイプを設定する必要があります。

JSON RPCの場合、ほとんどのJSONRPCサーバーはPOST HTTPメソッドで動作し、コンテンツタイプは常にapplication/jsonであるため、作業は大幅に簡略化されます。これにより、クライアント側で適切なHTTPメソッドとコンテンツ設定を使用することを忘れなくて済みます。

サーバーがクライアントに公開したいさまざまなメソッドや機能に対して、個別のコントローラーを作成する必要はありません。

なぜREST:

サーバーがクライアント側に公開したい機能ごとに別々のURLがあります。その結果、あなたはこれらのURLを埋め込むことができます。

これらの点のほとんどは議論の余地があり、人の必要性に完全に依存しています。

7
Umer Farooq

私は、いつものように、それは依存すると思います...

RESTには広く一般からの支持があるという大きな利点があり、これはたくさんのツールや本を意味します。さまざまな組織の多数の消費者によって使用されるAPIを作成する必要がある場合は、それが唯一の理由で行われる方法です。それが一般的です。プロトコルとしては、コマンドをURL /動詞/応答にマップするにはまったく異なる方法が多すぎるため、もちろん完全に失敗します。

したがって、バックエンドと対話する必要がある単一ページのWebアプリケーションを作成するときには、RESTは複雑すぎると思います。この状況では、アプリとAPIが一緒に進化する可能性があるため、長期的な互換性について心配する必要はありません。

私はかつてRESTで単一ページのWebアプリを始めましたが、Webアプリとサーバー間のきめ細かいコマンドがすぐに私を狂わせました。パスパラメータとしてエンコードする必要がありますか。体の中では?クエリパラメータヘッダー? URL /動詞/応答の設計の後、私はこの混乱をJavascript、Javaのデコーダーにコーディングしてから、実際のメソッドを呼び出す必要がありました。それには多くのツールがありますが、ドメインコードにHTTPセマンティクスを含まないのは本当に厄介です。これは本当に悪い習慣です。 (凝集)

中複雑なサイト用のSwagger/OpenAPIファイルを作成し、そのファイル内のリモートプロシージャを記述する単一のJavaインターフェイスと比較します。複雑さの増加は驚異的です。

そのため、単一ページのWebアプリケーションについてRESTからJSON-RPCに切り替えました。 aIは、サーバー上のJavaインターフェースをエンコードしてそれをブラウザーに出荷する小さなライブラリーを開発しました。ブラウザでは、これによりアプリケーションコードに対するプロキシが作成され、各機能に対して約束が返されました。

繰り返しになりますが、RESTは、有名であり、したがって十分にサポートされているという理由だけでその位置を占めています。基盤となるステートレスなリソースの哲学と階層モデルを認識することも重要です。ただし、これらの原則はRPCモデルでも同じように簡単に使用できます。 JSON RPCはHTTP上で動作するので、この分野でRESTと同じ利点があります。違いは、これらの原則にうまく対応しないこれらの関数に必然的に遭遇したとき、あなたは多くの不必要な仕事をすることを強制されないことです。

2
Peter Kriens

間違った質問:存在しないマニキュアを課します!

JSON-RPCを "less verb"(noメソッド)と共に使用して、sendo id、parameters、エラーに必要な最小限の標準化を維持することができますコードと警告メッセージ。 JSON-RPC標準では、「あなたはRESTにはなれません」とは書かれておらず、基本的な情報をどのようにまとめるかが書かれています。

"REST JSON-RPC"が存在します!最小限の情報パッキングのための、シンプルで堅実な契約による、[ベストプラクティス]のRESTです。


(から この答え と教訓的な文脈から)

RESTを扱うとき、それは一般的にリソースの観点から考えることから始めるのを助けます。この場合、リソースは単に「銀行口座」ではありませんが、その銀行口座のトランザクションです...しかしJSON-RPCは「method」パラメータを必須としておらず、すべてエンドポイントの「path」でエンコードされています。

  • RESTJSON要求POST /Bank/Account/John/Transactionを付けて{"jsonrpc": "2.0", "id": 12, "params": {"currency":"USD","amount":10}}を付けて預けます。
    JSONレスポンスは{"jsonrpc": "2.0", "result": "sucess", "id": 12}のようなものです。

  • RESTPOST /Bank/Account/John/Transactionを使用した撤回...同様。

  • ... GET /Bank/Account/John/Transaction/12345@13 ...これは、その正確な取引のJSONレコードを返す可能性があります(たとえば、ユーザーは通常、自分のアカウントの借方と貸方のレコードを望んでいます)。 {"jsonrpc": "2.0", "result": {"debits":[...],"credits":[...]}, "id": 13}のようなもの。 (REST)GET要求に関する規約には、 "@ id"によるidのエンコードを含めることができるため、JSONを送信する必要はありませんが、それでも応答パックでJSON-RPCを使用します。

2
Peter Krauss

RESTはHTTPと密接に関連しているため、HTTPを介してAPIを公開するだけであれば、RESTがほとんどの状況に適しています(すべてではありません)。ただし、メッセージングやWebソケットなどの他のトランスポートを介してAPIを公開する必要がある場合は、RESTは該当しません。

2
dtoux

リソースを要求する場合は、RESTful APIのほうが設計上優れています。単純なCRUD以外にも多くのパラメータと複雑なメソッドを含む複雑なデータを要求する場合は、RPCが正しい方法です。

1
Adrian Liu

理解しやすいWebアプリケーション用のAPIを開発するには、RESTとJSON-RPCの間でJSON-RPCを選択することをお勧めします。 JSON-RPCは、メソッド呼び出しと通信へのマッピングが容易に理解できるため、推奨されています。

最適なアプローチを選択することは、制約や主な目的によって異なります。例えば、パフォーマンスが主要な特性である限り、JSON-RPC(例えば、High Performance Computing)を利用することをお勧めします。ただし、他の人が推測できる汎用インターフェースを提供するために主な目的が不可知論者であることである場合は、RESTを使用することをお勧めします。両方の目標を達成する必要がある場合は、両方のプロトコルを含めることをお勧めします。

JSON-RPCからRESTを実際に分離しているのは、アーキテクチャの柔軟性を確認する一連の慎重に検討された制約に追いついているということです。制約は、クライアントとサーバーが互いに独立して成長することができること(クライアントのアプリケーションと混乱することなく変更ができること)を保証します。呼び出しはステートレスです(状態はハイパーメディアと見なされます)。インターフェースは対話のために提供され、APIは階層化されたシステム上で高度化されています(Hall、2010)。 JSON-RPCは迅速で使いやすいですが、前述のようにリソースとパラメータは密接に関連しており、GET/POSTに対して_を使用する動詞(api/addUser、api/deleteUser)に依存する可能性があります。RESTはHTTPで疎結合リソース(api/users)を配信します。 REST AP​​Iは、GET、PUT、POST、DELETE、PATCHなどのいくつかのHTTPメソッドに依存しています。 RESTは、経験の浅い開発者にとっては実装が少し難しいです。

JSON(JavaScript Object Notationと表記)は軽量のデータ交換フォーマットであるため、人間にとって読み書きは容易です。マシンが解析して生成するのは面倒なことではありません。 JSONは、完全に言語に依存しないテキスト形式ですが、C#、C、C++、Java、Perl、JavaScript、Python、およびその他多数からなる言語ファミリーのプログラマーに慣れ親しんだ規約を実践しています。このような特性により、JSONは完璧なデータ交換言語であり、選択するのに適しています。

1
SinghKunal

私はRPCプロトコルにvdataを使います。 http://vdata.dekuan.org/

1、PHPとJavaScriptはどちらも問題ありません。 2、クロスオリジンリソース共有(CORS)呼び出しはまだ大丈夫です。

0
Liu Qixing

私が人々が言及するのを忘れたワンポイントがあると思います。すでにWebアプリをお持ちの場合は、RESTが望ましいでしょう。これは、いずれにしてもアプリサーバーが必要で、httpsを使用して両方を保護できるからです。アプリケーションサーバーを使用する場合は、RPCを使用することをお勧めします。アプリケーションサーバーを設定して設定する必要がなくなるため、面倒な作業です。それ以外に、私はどちらにも本当の根本的な利点を見ません。

0
max