This extension extends the CController and gives it JSON capabilities for fast development of JSON web services and their documentation.
Requirements ¶
This has been tested on Yii 1.1.10+
Features ¶
Action Input parameters ¶
You define your input parameters as objects, which are actually the JSON-decoded payload of your caller's request. Decoding and validation takes place transparently, as long as your input object is a subclass of CBJsonModel
.
Action Return values ¶
You return your action's response with return
instead of render
. It's highly suggested that your return objects are subtypes of CBJsonModel or arrays of such objects. Still, this is a suggestion, of course you can return anything that json_encode() accepts, as long as you trust what you're exposing to your caller.
PHPdoc for your json services ¶
The above allow for automatic documentation of your services, e.g. using apigen. The produced documentation can be then published and let your clients/callers know exactly what they should pass as input and what to expect as output.
Consistent error and exception handling ¶
Error handling is done automatically, i.e. whenever an exception or PHP error is thrown, a standard-format JSON is returned which your caller may then parse and handle.
Installation ¶
Download and extract the code into /protected/extensions/bogo-yii-json-service/
folder.
Add the following lines in the import array of your /protected/config/main.php
to make the extensions classes visible to your code and enable CBHttpRequest functionality in place of Yii's standard CHttpRequest class:
return array(
// [..]
// autoloading model and component classes
'import'=>array(
// [..]
'ext.bogo-yii-json-service.components.*',
// [..]
),
// application components
'components'=>array(
// [..]
// Use json-capable http request
'request'=>array(
'class'=>'CBHttpRequest',
),
// [..]
),
// [..]
);
Demonstration ¶
Quick sample ¶
Below a sample code which highlights the usage of JSON capabilities. Things you should keep are:
- The controller
extends
theCBJsonController
component - The method accepts a
ProductQueryJson
object instead of looking into$_GET
/$_POST
- The method
return
s an array ofProductJson
objects instead of calling$this->render()
class ProductController extends CBJsonController
{
/**
* Find products.
*
* @param ProductQueryJson $queryJson Query criteria
* @return ProductJson[] Matching products
*/
public function actionFindProduct(ProductQueryJson $queryJson)
{
$foundProducts = Product::model()->scopeApplyQuery($queryJson)->findAll();
return ProductJson::createFromMany($foundProducts);
}
}
More detailed usage ¶
For more details and examples, see the the demo page
Your API's public documentation ¶
Here's the demo controller documentation you get by using this extension in conjunction with proper phpdoc comments and apigen.
Resources ¶
Similar Extensions ¶
- JApi, short for JSON API, is an action handler for Yii.
some help?
Hi
I've just tried to use this as I'm looking at a few rest/json implementations. I'm just basically just return a basic array via the controller at the moment but I seem to be getting the json but also an error message below: https://github.com/thiswayup/yiiRestTest/blob/master/errorOutput.txt
I've also put all the files onto git in the same repo. I wonder if you can give some tips?
Fixed ugly reference to $_GET['r']
Hi thiswayup,
thanks for your input, it turns out you were right. It was the debug/logging part which assumed the called controller action is in $_GET['r']. I've uploaded a patch in the latest commit of the master branch.
If you have the chance to verify it works for you, too, please let me know so I upload a revision here, too.
Btw, the documentation I've provided is quite draft, so if you think any addition from my side would help, please let me know.
It worked!
Looks like that did it!
Thanks!
general questions about bogo yii json service
Thank you to K.F. for this extension.
i'm somewhat of a newbie. can anyone help with these few questions?
-is bogo yii json service extension, "inspired" on any previous open source code (libraries, etc), or did you create it from scratch expressly for within yii? what is "bogo"? just a random name?
-how can CRUD operations get done, using bogo yii json service?
-by the way, my recommendation for you might be, don't spend time working on the "development/testing" work-around of using $_GET variables, ($_GET['jsin'] etc) instead,
recommend a way to send "test" requests, i am thinking: such as:
chrome://restclient/content/restclient.html
.. it seems a better way, to test, than with $_GET work-around?
-by the way, do you (or anyone) plan on supporting in the future?
Thanks!
@xmvyii
Hi xmvyii,
thanks for trying the extension. Here are some answers to your questions:
So the implementation guidelines were the following: Provide a mechanism which requires the least extra effort from the JSON API developer and least "modifications" to the standard CController behaviour of Yii (which people are used to) and provides documentation to the API consumers using existing tools (apigen, phpdoc, etc.) without inferior quality, when compared to other languages and platforms.
CRUD operations work as you know them, with two major exceptions:
You made a good point though: I'll try to create an example with simple CRUD operations and add it either in this page or the github wiki. Then I'll take a look at the possible benefits of introducing a scaffolding template for gii.
Taking into consideration that GET imposes a limit on the length of the request URL, it's always best to use POST and a rest-client.
br, kf
Added demo documentation output
FYI, I split the example in a separate demo link to make the intro page shorter and added a sample api documentation output.
restful
My project team co-workers are telling me, i should choose a RESTful service. Although i am a newbie to "modern" web development, and need to ask them, "why" they think that's important. As you've said, yours is not RESTful, and as i understand, the extension was created basically to provide a simple, non-restful JSON request-reply system (service), along with your preferred "style of documentation". Correct me if i'm wrong!
If my team insists or restful, i will probably look into the "How to create a REST api" (on yii) wiki:
http://www.yiiframework.com/wiki/175/how-to-create-a-rest-api/
How to use?
Hello,
I tried the following url
http://localhost/MovilServices/index.php?r=Product/FindProduct
but not found, return error
"message":"ProductController::actionFindProduct: No argument passed for mandatory parameter \"queryJson\"",
"code":0,
"type":"CHttpException",
some idea of the error?
thanks.
No argument passed for mandatory parameter
Hi Alexis,
yes, this happens because you have not passed any json body in your request. Supposing your json input would look like this:
{"somefield":"somevalue"}
you have three options here:
a. You are just trying out stuff, so you can pass your json object as a get parameter, in a simple GET request using the special "jsin" GET parameter:
http://localhost/MovilServices/index.php?r=Product/FindProduct&jsin={"somefield":"somevalue"}
b. You can pass your json as the body of a POST request, but you must also include the Content-Type: application/json header in your request
c. You can make the input object optional, by doing this in your action:
class ProductController { actionFindProduct(JsonClassType $queryJson = null) { } }
I understand a few of the above details should be documented but I'm currently re-organizing a few things to make the extension more flexible. I'm hoping I'll have more soon enough :)
QueryJson
Thanks, it worked.
Now I have another question
in the ProductQueryJson class there are 3 properties
$filterMinPrice,$resultsLimit,$resultsOrderBy
ProductController /** * Find products. * * @param ProductQueryJson $queryJson Query criteria * @return ProductJson[] Matching products */ public function actionFindProduct(ProductQueryJson $queryJson) { $foundProducts = Product::model()->scopes($queryJson)->findAll() return ProductJson::createFromMany($foundProducts); }
I'm trying that you use in the query
http://localhost/MovilServices/index.php?r=Product/FindProduct&jsin={"filterMinPrice":"10","resultsLimit":"10","resultsOrderBy":"title"}
but not found :|
Fatal error: Call to a member function findAll() on a non-object
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.