JSON-RPC 2.0およびPHP

あなたが開発者であり、PHPでプロジェクトを持っている場合、彼は最終的に彼自身のAPIを実装する必要がありました-この記事は間違いなくあなたのためです;)。

JSON-RPC v1.0は2005年に登場し、5年後に2番目のバージョンが登場しました 。 JavaScriptおよびモバイルアプリケーションの時代において、多くの開発者は、既成のシンプルな標準ではなく、独自のバイクを使用しています。

なぜJSON-RPC、さらには2.0なのか?


主な機能を強調してみます。

バージョン1.0に精通している人にとって、2.0の重要な革新はパラメーターとコールキューと呼ばれていました。
簡単なリクエスト/レスポンスは次のとおりです。
--> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3} <-- {"jsonrpc": "2.0", "result": 19, "id": 3} --> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1} <-- {"jsonrpc": "2.0", "result": 19, "id": 1} --> [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}, {"jsonrpc": "2.0", "method": "foobar", "id": "2"} ] <-- [ {"jsonrpc": "2.0", "result": 7, "id": "1"}, {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found."}, "id": "2"} ] 


プログラミングのこの複雑な「創造的な」世界では、疑問が常に生じます。準備ができているのか、自分の何かを書くのか?

完璧な世界。 何が必要ですか?


通常どおり、検索/取得するツールの基準を定義します。

開始するには十分です。

理論のビット


なぜなら JSON-RPCはかなり新しいプロトコルですが、まだ完全には承認されていない瞬間があります。 それらの1つは、Dojoによって提案されたサービスマッピング記述です。 SMDは、メソッドから始めて、デプロイされた戻り値型で終わるWebサービスを完全に記述することができます。 残念ながら、 Zend_Json_Server 、inputExフレームワーク( テストフォームの生成 )、 Dojoフレームワークなど、実装をサポートするソリューションはほとんどありません。

既存のソリューションの検索に移りましょう。

PHPの既存の実装


ウィキペディアのタブレットからクライアントのリストを取得しました。
php-json-rpcjsonrpc2phpチボカジュニアjson-rpc-phpJSONRpc2ゼンド
ジョンソン
サーバー
zoServices
サーバー
コンプライアンス-バッチモードでの通知の正しいサポート。
+オプションの名前付きパラメーターはありません+++オプションの名前付きパラメーターはありません
ファイル数-2> 7361> 56
SMD回路------+-
テスト-+-+-++-
内部実装(1..5)-4
エクスポートされた関数の手動マッピング
3.このような単純なタスクには実装が複雑すぎる44.難しい4.マジックインサイド!4+。 ゼンド3。
お客様
コンプライアンスバッチと通知なし-+++バッチなし-通知がありません
ファイル数1-> 7421-6
テスト---+-+--
内部実装(1..5)4-3.メソッドを呼び出すための追加手順444+。 :)-3
自動生成--------

スマートリーダーは、それがどのような違いを生み、実装に使用するファイルの数を主張するかもしれませんが、すべてを1つに接着することができます。 はい、できますが、これは追加の追加アクションです。

ご覧のとおり、私たちに合った、ファイルなしで安全に使用できる「理想的な」ソリューションはありません。 他のプラットフォームの方がずっといいと思います:)
一般的に未完成のプロジェクトがありますが、エクスポートされたAPI(サーバー、smd-schema、クライアント生成)を使用する完全なサイクルを提供できるソリューションはありません。
また、PHPを作成しようとしている開発者(JavaやC#など)を本当に理解していません。 ほとんどの場合、PHPは要求/応答スキームで使用され、状態を含むアプリケーションサーバースキームでは使用されません。 スクリプトは、コンパイルされたプライベートライブラリではありません。

「準備が整ったものを使用する」または「自分で作成する」という質問に対する答えは明らかです。

Eazy JSON-RPC 2.0


GitHubのプロジェクト。 前に示したすべての要件が実装されています:)

サーバー

2つのユースケースがあります:BaseJsonRpcServerクラスを継承するか、そのインスタンスを作成して、エクスポートされたオブジェクトをコンストラクターに渡します。
 <?php include 'BaseJsonRpcServer.php'; include 'tests/lib/DateTimeRpcService.php'; //   $server = new DateTimeRpcService(); //  new BaseJsonRpcServer( new DateTimeService() ); $server->Execute(); 

したがって、DateTimeRpcServiceクラスのすべてのパブリックメソッドを公開しました。 SMDスキームは、 smd GETパラメーター(たとえば、 eazyjsonrpc / example-server.php?Smd )から取得できます。 スキームを構築するとき、phpDocブロックが考慮されます。
どんな回路があるのか​​......
 {"transport":"POST","envelope":"JSON-RPC-2.0","SMDVersion":"2.0","contentType":"application\/json","target":"\/example-server.php","services":{"GetTime":{"parameters":[{"name":"timezone","optional":true,"type":"string","default":"UTC"},{"name":"format","optional":true,"type":"string","default":"c"}],"description":"Get Current Time","returns":{"type":"string"}},"GetTimeZones":{"parameters":[],"description":"Returns associative array containing dst, offset and the timezone name","returns":{"type":"array"}},"GetRelativeTime":{"parameters":[{"name":"text","optional":false,"type":"string","description":"a date\/time string\r"},{"name":"timezone","optional":true,"type":"string","default":"UTC"},{"name":"format","optional":true,"type":"string","default":"c"}],"description":"Get Relative time","returns":{"type":"string"}},"Implode":{"parameters":[{"name":"glue","optional":false,"type":"string"},{"name":"pieces","optional":true,"type":"array","default":["1","2","3"]}],"description":"Implode Function","returns":{"type":"string","description":"string"}}},"description":"Simple Date Time Service"} 



クライアント

再び2つの用途が考えられます:BaseJsonRpcClientクラスのインスタンスを作成し、コンストラクターでWebサービスリンクを渡すか、ジェネレーターを使用します。
 <?php include 'BaseJsonRpcClient.php'; $client = new BaseJsonRpcClient( 'http://eazyjsonrpc/example-server.php' ); $result = $client->GetRelativeTime( 'yesterday' ); 


発電機

SMDスキームに基づいて、サーバーを操作するためのクラスを生成できます( DateTimeServiceClient.phpの例を参照)。 これを行うには、ジェネレーターを呼び出します。
 php JsonRpcClientGenerator.php http://eazyjsonrpc/example-server.php?smd DateTimeServiceClient 

コマンドの結果は、必要なメソッドを含むDateTimeServiceClient.phpファイルになります。

軟膏で飛ぶ

JSON-RPCでclass- > method()を呼び出す暗黙のルールは、 class.methodをメソッドの名前として(ドットを使用して)使用しています。
現在の実装では、このような機能は提供されていません。 urlはエクスポートされたクラスであると想定されているため、点線のオプションは表示されなくなります:)。 クライアント側に関しては、ここにいつでも追加できます。これは単なるPHPです。

また、SMDでは、戻り値の型をプロパティとオブジェクトの形で記述することもできますが、実装の複雑さを考慮して、この瞬間は省略します。

詳細なドキュメントを探している人のために、メソッドの名前、それらへのphpDocコメント、およびサーバーまたはクライアントのソースコードを読むことをお勧めします。

ライフハック


認証には何がありますか?

いくつかの実装オプションがあります。
  1. HTTP基本認証を使用します。 クライアントでは、ユーザー名とパスワードを$ CurlOptions配列に追加するだけです:)
  2. HTTPヘッダーを介してトークンを使用します。 トークンを取得するには、必要なメソッドを記述できます。
  3. メソッドパラメータとしてトークンを使用します。

ファイルのアップロードはどうですか?

base64でファイルをエンコードし、それを何らかのフィールドに送信するという奇妙なオプションを提供する人もいます。
多かれ少なかれ通常の解決策は、ファイルのダウンロードを開始できるアドレスを通知するメソッドを実装することです。
 --> {"jsonrpc": "2.0", "method": "send_image", "params": ..., "id": 1} <-- {"jsonrpc": "2.0", "result": {"URL": "/exampleurl?id=12345", "maxsize": 10000000, "accepted-format":["jpg", "png"]}, "id": 1} -->      .      ,    --> {"jsonrpc": "2.0", "method": "send_done", "params": {"checksum": "1a5e8f13"}, "id": 2} <-- {"jsonrpc": "2.0", "result": "ok"} 

エラー処理

プロトコル自体は、 コードメッセージ、およびデータフィールドを持つエラーオブジェクトの存在をすでに提供しています。 呼び出されたメソッド内でBaseJsonRpcServerを使用する場合、 コードデータを渡す例外をスローできます 。 特定のコードを使用して、 メッセージを$ errorMessages配列に追加できます。

特定のフィールドのみを持つオブジェクトをエクスポートする

それはすべて完全にあなた次第ですが、どのように実装するかはそうなります。 オブジェクトの必要な配列への変換を実装するクラスObjectToJsonConverterを作成することのみをお勧めします。
 <?php class ObjectToJsonConverter { /** * @param City $city * @return array */ public static function GetCity( City $city ) { return array( 'id' => $city->cityId , 'name' => $city->title , 'region' => $city->region->title ); } } // -     return array_map( 'ObjectToJsonConverter::GetCity', $cities ); 


クライアント側オブジェクトに変換

繰り返しますが、それはすべてあなた次第です。 たとえば、必要なクラスを作成し、簡単なコンバーターを書き戻すことができます(変換のアイデアはMyShowsClient.php取得できます)

おわりに


記事を読んだ後、インタラクションプロトコルを選択するときにJSON-RPCが注意を奪われないことを願っています。
> 89%のコードのテストをカバーした後でも、「うまくいくようだ」としか言えません:)

Source: https://habr.com/ru/post/J150803/


All Articles