diff --git a/JsonRpc2/Controller.php b/JsonRpc2/Controller.php
index 0227acb..c158834 100644
--- a/JsonRpc2/Controller.php
+++ b/JsonRpc2/Controller.php
@@ -49,7 +49,7 @@ public function runAction($id, $params = [])
$resultData = [Helper::formatResponse(null, new Exception("Invalid Request", Exception::INVALID_REQUEST))];
} else {
foreach ($requests as $request) {
- if($response = $this->getActionResponse($request))
+ if($response = $this->getActionResponse($request, $id))
$resultData[] = $response;
}
}
@@ -67,11 +67,11 @@ public function runAction($id, $params = [])
* @throws \yii\web\HttpException
* @return Response
*/
- private function getActionResponse($requestObject)
+ private function getActionResponse($requestObject, $id)
{
$this->requestObject = $result = $error = null;
try {
- $this->parseAndValidateRequestObject($requestObject);
+ $this->parseAndValidateRequestObject($requestObject, $id);
ob_start();
$dirtyResult = parent::runAction($this->requestObject->method);
ob_clean();
@@ -178,7 +178,7 @@ public function bindActionParams($action, $params)
* Request has to be sent as POST and with Content-type: application/json
* @throws \yii\web\HttpException
*/
- private function initRequest($id)
+ protected function initRequest($id)
{
list($contentType) = explode(";", Yii::$app->request->getContentType()); //cut charset
if (!empty($id) || !Yii::$app->request->getIsPost() || empty($contentType) || $contentType != "application/json")
@@ -190,7 +190,7 @@ private function initRequest($id)
* @param $requestObject string
* @throws Exception
*/
- private function parseAndValidateRequestObject($requestObject)
+ protected function parseAndValidateRequestObject($requestObject, $id)
{
if (null === $requestObject)
throw new Exception("Parse error", Exception::PARSE_ERROR);
diff --git a/JsonRpc2/LightMethodProtocolTrait.php b/JsonRpc2/LightMethodProtocolTrait.php
new file mode 100644
index 0000000..7b9c20e
--- /dev/null
+++ b/JsonRpc2/LightMethodProtocolTrait.php
@@ -0,0 +1,83 @@
+
+ */
+trait LightMethodProtocolTrait
+{
+ /**
+ * @inheritdoc
+ */
+ protected function initRequest($id)
+ {
+ // parent will throw an exception if $id is non-empty, but we want to
+ // allow a non-empty $id in Light-mode
+ parent::initRequest('');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function parseAndValidateRequestObject($requestObject, $id)
+ {
+ if ($requestObject !== null)
+ {
+ // if method is specified both in the URL and in the $id, and
+ // they do not match, we throw an error
+ if (!empty($requestObject->method) && !empty($id) && $requestObject->method != $id)
+ {
+ throw new Exception("Invalid Request - method mismatch", Exception::INVALID_REQUEST);
+ }
+
+ // if the $requestObject method is not specified or isn't a string,
+ // use the $id from the URL instead
+ if ((empty($requestObject->method) || "string" != gettype($requestObject->method)) && !empty($id))
+ {
+ $requestObject->method = $id;
+ }
+ }
+
+ parent::parseAndValidateRequestObject($requestObject, '');
+ }
+}
diff --git a/README.md b/README.md
index 9f9ae88..4112aa9 100644
--- a/README.md
+++ b/README.md
@@ -112,6 +112,56 @@ documentation for related information.
+###Light Method Protocol
+If you wish, you may use a "light" method protocol that allows clients to
+encode the method name in the URL instead of in the "method" parameter of the
+request object. To do this, use the \JsonRpc2\LightMethodProtocolTrait in your
+instance of \JsonRpc2\Controller like
+
+~~~php
+class ServicesController extends \JsonRpc2\Controller
+{
+ use \JsonRpc2\LightMethodProtocolTrait;
+}
+~~~
+
+One advantage of the light method format is that web server access logs will
+contain the method invoked, because it is in the URL. The standard "heavy"
+format will not, because the method is inside the POST data.
+
+Without the LightMethodProtocol, a client would post to
+```
+http://yoursite/services
+```
+with data
+```javascript
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "update",
+ "params": ["world"]
+}
+```
+
+However, with the LightMethodProtocol, a client could instead post to
+```
+http://yoursite/services/update
+```
+with data
+```javascript
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "params": ["world"]
+}
+```
+
+The method may be specified both in the URL and in the request object
+provided that they match. If the method is specified in both places, an
+error is thrown if they do not match.
+
+
+
###Params validation
For validation params data you MUST create [phpDoc @param](http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.param.pkg.html) tags comments with type to action method.
After that param data will be converted to documented type.