Skip to content

Commit c9489b2

Browse files
authored
Release v3.0.0
Migrate to guzzle http client Update json rpc client - now it returns result and throw rpc/http errors via exceptions. Update generator to use new json rpc client
2 parents 7208658 + 6655c38 commit c9489b2

18 files changed

+746
-369
lines changed

README.md

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
eazy-jsonrpc
22
============
3+
[![Latest Version](https://img.shields.io/github/release/sergeyfast/eazy-jsonrpc.svg?style=flat-square)](https://github.com/sergeyfast/eazy-jsonrpc/releases)
4+
[![Total Downloads](https://img.shields.io/packagist/dt/sergeyfast/eazy-jsonrpc.svg?style=flat-square)](https://packagist.org/packages/sergeyfast/eazy-jsonrpc)
35

46
PHP JSON-RPC 2.0 Server/Client Implementation with Automatic Client Class Generation via SMD
57

@@ -11,21 +13,44 @@ SMD Schema available via /server.php?smd
1113
__Public Namespace__
1214

1315
* Inherits your exposed class from BaseJsonRpcServer or create `new BaseJsonRpcServer( $instance );`
14-
* `$server->execute();`
16+
* `$server->Execute();`
1517

1618
__Multiple Namespaces__
1719

1820
* Create `new BaseJsonRpcServer();`
1921
* Call `$server->RegisterInstance( $instance, $namespace )` as many times as you need
20-
* `$server->execute();`
22+
* `$server->Execute();`
2123

2224

2325
Client
2426
------
2527

26-
* Generate Client from SMD Schema from generator/ `php JsonRpcClientGenerator <smd-file> <class-name>`
27-
* Create client instance `$client = <class-name>::GetInstance();` or `$client = new <class-name>( <url> );`
28-
* Use it `$result = $client->Method()`; :)
28+
* Generate Client from SMD Schema from generator/ `php JsonRpcClientGenerator.php <smd-file> <class-name>`
29+
* Use it:
30+
```
31+
$client = <class-name>::GetInstance(<url>);
32+
33+
try {
34+
$result = $client->Method();
35+
} catch (BaseJsonRpcException $e) {
36+
// work with exception
37+
}
38+
```
39+
40+
Client with typed returns by rpcgen
41+
------
42+
43+
* Generate Client from SMD Schema with [rpcgen](https://github.com/vmkteam/rpcgen) and save it to `RpcClient.php`
44+
* Use it:
45+
```
46+
$client = RpcClient::GetInstance(<url>);
47+
48+
try {
49+
$result = $client->Method();
50+
} catch (BaseJsonRpcException $e) {
51+
// work with exception
52+
}
53+
```
2954

3055
Doc
3156
------

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929
},
3030
"target-dir":"",
3131
"require":{
32-
"php":">=5.4.0",
32+
"php":">=7.2.0",
3333
"ext-curl": "*",
34-
"ext-json": "*"
34+
"ext-json": "*",
35+
"netresearch/jsonmapper": "^4.0",
36+
"guzzlehttp/guzzle": "^7.3"
3537
},
3638
"require-dev":{
3739
"phpunit/phpunit": "4.8.*"

generator/JsonRpcClientGenerator.php

Lines changed: 110 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class JsonRpcClientGenerator {
3939
* @param array $smd SMD Schema
4040
* @param string $className
4141
*/
42-
public function __construct( $url, $smd, $className ) {
42+
public function __construct( string $url, array $smd, string $className ) {
4343
$this->url = $url;
4444
$this->smd = $smd;
4545
$this->className = $className;
@@ -56,12 +56,22 @@ private function getHeader() {
5656
$date = date( 'd.m.Y G:i' );
5757
$result = <<<php
5858
<?php
59+
/**
60+
* PHP RPC Client by JsonRpcClientGenerator
61+
* @date {$date}
62+
*/
63+
64+
namespace JsonRpcClient;
65+
66+
use EazyJsonRpc\BaseJsonRpcClient;
67+
use EazyJsonRpc\BaseJsonRpcException;
68+
use GuzzleHttp\Exception\GuzzleException;
69+
use JsonMapper_Exception;
70+
5971
/**
6072
* {$description}
61-
* @author JsonRpcClientGenerator
62-
* @date {$date}
6373
*/
64-
class {$this->className} extends \EazyJsonRpc\BaseJsonRpcClient {
74+
class {$this->className} extends BaseJsonRpcClient {
6575
php;
6676

6777
return $result;
@@ -73,121 +83,163 @@ class {$this->className} extends \EazyJsonRpc\BaseJsonRpcClient {
7383
* @param $methodData
7484
* @return string
7585
*/
76-
public function getMethod( $methodName, $methodData ) {
77-
$newDocLine = PHP_EOL . str_repeat( ' ', 9 ) . '*';
78-
$description = !empty( $methodData['description'] ) ? $methodData['description'] : $methodName;
86+
public function getMethod( $methodName, $methodData ): string {
87+
$newDocLine = PHP_EOL . str_repeat( ' ', 8 ) . '*';
88+
$description = sprintf( '<%s> RPC method', $methodName );
89+
$description .= !empty( $methodData['description'] ) ? $newDocLine . ' ' . trim( $methodData['description'] ) : '';
90+
$description = str_replace( "\n", PHP_EOL, $description );
7991
$strDocParams = '';
80-
$strParamsArr = [ ];
81-
$callParamsArr = [ ];
92+
$strParamsArr = [];
93+
$callParamsArr = [];
8294
$methodName = str_replace( '.', '_', $methodName );
8395

84-
// Add Default Parameter = IsNotification
85-
$methodData['parameters'][] = [
86-
'name' => 'isNotification',
87-
'optional' => 'true',
88-
'type' => 'bool',
89-
'default' => false,
90-
'description' => 'set to true if call is notification',
91-
];
92-
9396
// params
9497
if ( !empty( $methodData['parameters'] ) ) {
9598
// Set Doc Params
9699
foreach ( $methodData['parameters'] as $param ) {
97-
$name = $param['name'];
98-
$strParam = '$' . $name;
99-
$strDocParamsArr = [ $newDocLine ];
100-
$strDocParamsArr[] = '@param';
101-
100+
$name = $param['name'];
101+
$strDocParam = $newDocLine;
102+
$strDocParam .= " @param";
102103
if ( !empty( $param['type'] ) ) {
103-
$strDocParamsArr[] = $param['type'];
104+
$strDocParam .= " " . $this->getPhpType( $param['type'] );
105+
}
106+
$strParam = $this->getPhpType( $param['type'] ) . ' $' . $name;
107+
$optionalParam = !empty( $param['optional'] );
108+
if ( $optionalParam ) {
109+
$strDocParam .= '|null';
104110
}
105111

106-
$strDocParamsArr[] = '$' . $name;
107-
if ( !empty( $param['optional'] ) ) {
108-
$strDocParamsArr[] = '[optional]';
112+
$strDocParam .= ' $' . $name;
113+
if ( $optionalParam ) {
114+
$strDocParam .= ' [optional]';
109115
}
110116

111117
if ( !empty( $param['description'] ) ) {
112-
$strDocParamsArr[] = $param['description'];
118+
$strDocParam .= " " . $param['description'];
113119
}
114120

115121
if ( array_key_exists( 'default', $param ) ) {
116122
$strParam .= sprintf( ' = %s', var_export( $param['default'], true ) );
123+
} else {
124+
if ( $optionalParam ) {
125+
$strParam .= ' = null';
126+
}
117127
}
118128

119-
$strDocParams .= rtrim( implode( ' ', $strDocParamsArr ) );
129+
$strDocParams .= rtrim( $strDocParam );
120130
$strParamsArr[] = $strParam;
121131
$callParamsArr[$name] = sprintf( "'%s' => $%s", $name, $name );
122132
}
123133
}
124-
125-
$strParams = ' ' . trim(
126-
str_replace(
127-
[ "\n", ',)', 'array (' ],
128-
[ '', ')', 'array(' ],
129-
implode( ', ', $strParamsArr )
130-
), ', ' ) . ' ';
131-
132-
unset( $callParamsArr['isNotification'] );
133-
134+
$strDocParams .= $newDocLine . ' @param bool $isNotification [optional] set to true if call is notification';
135+
136+
$strParams = str_replace(
137+
[ "\n", ',)', 'array (' ],
138+
[ '', ')', 'array(' ],
139+
implode( ', ', $strParamsArr )
140+
);
141+
142+
$strParams .= ', $isNotification = false ';
143+
$strParams = ' ' . trim( $strParams, ', ' ) . ' ';
144+
$returnType = '';
145+
$optionalReturn = '';
146+
$strDocReturns = $newDocLine . ' @return mixed';
147+
$strReturnType = '';
134148
// returns
135-
if ( !empty( $methodData['returns'] ) && !empty( $methodData['returns']['type'] ) && is_string( $methodData['returns']['type'] ) ) {
136-
$strDocParams .= $newDocLine . ' @return \EazyJsonRpc\BaseJsonRpcCall (result: ' . $methodData['returns']['type'] . ')';
149+
if ( !empty( $methodData['returns'] ) ) {
150+
$strDocReturns = '';
151+
if ( !empty( $methodData['returns']['type'] ) && is_string( $methodData['returns']['type'] ) ) {
152+
$returnType = $this->getPhpType( $methodData['returns']['type'] );
153+
$strDocReturns .= $newDocLine . ' @return ' . $returnType;
154+
}
155+
if ( !empty( $methodData['returns']['optional'] ) ) {
156+
$optionalReturn = '?';
157+
$strDocReturns .= '|null';
158+
}
159+
if ( !empty( $methodData['returns']['description'] ) ) {
160+
$strDocReturns .= ' ' . $methodData['returns']['description'];
161+
}
162+
if ( $returnType != 'mixed' ) {
163+
$strReturnType = sprintf( ': %s%s', $optionalReturn, $returnType );
164+
}
137165
}
138-
166+
$strDocParams .= $strDocReturns;
139167
$callParamsStr = implode( ', ', $callParamsArr );
140168
if ( !empty( $callParamsStr ) ) {
141169
$callParamsStr = sprintf( ' %s ', $callParamsStr );
142170
}
143171

144172

145-
$result = <<<php
173+
return <<<php
146174
/**
147-
* {$description}{$strDocParams}
148-
*/
149-
public function {$methodName}({$strParams}) {
150-
return \$this->call( __FUNCTION__, array({$callParamsStr}), \$this->getRequestId( \$isNotification ) );
175+
* {$description}{$strDocParams}
176+
* @throws BaseJsonRpcException
177+
* @throws GuzzleException
178+
* @throws JsonMapper_Exception
179+
*/
180+
public function {$methodName}({$strParams})$strReturnType {
181+
return \$this->call( __FUNCTION__, '$returnType', [{$callParamsStr}], \$this->getRequestId( \$isNotification ) );
151182
}
152183
153184
php;
154-
return $result;
155185

156186
}
157187

158188

159189
/**
160190
* Get Footer
161191
*/
162-
private function getFooter() {
163-
$url = $this->url;
164-
$urlInfo = parse_url( $url );
192+
private function getFooter(): string {
193+
$rpcUrl = $this->url;
194+
$urlInfo = parse_url( $rpcUrl );
165195
if ( !empty( $urlInfo ) ) {
166-
$url = sprintf( '%s://%s%s', $urlInfo['scheme'], $urlInfo['host'], $this->smd['target'] );
196+
$rpcUrl = sprintf( '%s://%s%s', $urlInfo['scheme'], $urlInfo['host'], $this->smd['target'] );
167197
}
168198

169-
$result = <<<php
199+
return <<<php
170200
171201
172202
/**
173203
* Get Instance
204+
* @param \$url string
174205
* @return {$this->className}
175206
*/
176-
public static function GetInstance() {
177-
return new self( '{$url}' );
207+
public static function GetInstance( string \$url ): {$this->className} {
208+
return new self( \$url );
178209
}
179210
180211
}
181212
php;
213+
}
182214

183-
return $result;
215+
216+
/**
217+
* Return PHP type from SMD type
218+
* @param string $smdType
219+
* @return string
220+
*/
221+
private function getPhpType( string $smdType ): string {
222+
switch ( $smdType ) {
223+
case "string":
224+
return "string";
225+
case "object":
226+
case "array":
227+
return "array";
228+
case "boolean":
229+
return "bool";
230+
case "float":
231+
return "float";
232+
case "integer":
233+
return "int";
234+
}
235+
return "mixed";
184236
}
185237

186238

187239
/**
188240
* Save to File
189241
*/
190-
public function Generate() {
242+
public function Generate(): string {
191243
$this->result = $this->getHeader();
192244

193245
foreach ( $this->smd['services'] as $methodName => $methodData ) {
@@ -205,7 +257,7 @@ public function Generate() {
205257
* Save To File
206258
* @return int
207259
*/
208-
public function SaveToFile() {
260+
public function SaveToFile(): int {
209261
return file_put_contents( $this->className . '.php', $this->Generate() );
210262
}
211263
}

0 commit comments

Comments
 (0)