-
-
15 Jan 2014 01:00:19 UTC
- Distribution: CatalystX-ExtJS-Direct
- Module version: v2.1.5
- Source (raw)
- Browse (raw)
- Changes
- Homepage
- How to Contribute
- Repository
- Issues (2)
- Testers (187 / 413 / 0)
- Kwalitee
Bus factor: 0- % Coverage
- License: bsd
- Activity
24 month- Tools
- Download (18.34KB)
- MetaCPAN Explorer
- Permissions
- Subscribe to distribution
- Permalinks
- This version
- Latest version
NAME
CatalystX::ExtJS::Tutorial::Direct - Introduction to CatalystX::ExtJS::Direct
VERSION
version 2.1.5
INTRODUCTION
Ext.Direct is an ExtJS component which creates classes and methods according to an API provided by the server. These methods are used to communicate with the server in a Remote Procedure Call fashion. This requires a router on the server side to route the requests to the matching method.
CatalystX::ExtJS::Direct will take care of creating the API and provides a convenient way to include it in your web application as well as providing a router which takes care of calling the correct Catalyst actions when it comes to a request.
Please find a working example of the tutorial at
/tutorial
in the CatalystX::ExtJS distribution.EXAMPLES
Simple Calculator
Run steps 1 to 5 from "FIRST STEPS" in CatalystX::ExtJS::Tutorial.
Every controller which wants to add an action to the Ext.Direct API needs to consume the CatalystX::Controller::ExtJS::Direct role. Furthermore each action which should be accessible requires the
Direct
attribute. This simple example adds two numbers and returns the result:package MyApp::Controller::Calculator; use Moose; BEGIN { extends 'Catalyst::Controller' }; with 'CatalystX::Controller::ExtJS::Direct'; use JSON::XS; sub add : Chained('/') : Path : CaptureArgs(1) { my($self,$c, $arg) = @_; $c->stash->{add} = $arg; } sub add_to : Chained('add') : PathPart('to') : Args(1) : Direct('add') { my($self,$c,$arg) = @_; $c->res->body( $c->stash->{add} + $arg ); } sub echo : Local : Direct : DirectArgs(1) { my ($self, $c) = @_; $c->res->content_type('application/json'); $c->res->body(encode_json($c->req->data)); }
As you can see the
add_to
action has theDirect
attribute attached to it. Direct actions can only be attached to endpoints of Chained actions. By default the method's name for the API is the same as the action's name. In this case however we changed the name of the action toadd
by adding this as parameter to theDirect
attribute.If you add the Direct attribute to a normal action (e.g.
Local
) it has no arguments by default. To change that you can add theDirectArgs
attribute and enter the number of arguments there. If you addDirectArgs
to a Chained endpoint the number of arguments will be added to the number of arguments required to call this endpoint.The
echo
action accepts one argument from the Direct API. You can access this argument via$c->req->data
, which is always an arrayref and includes all arguments. We set the content type toapplication/json
to make sure that the body is not serialized twice. That is, if you would not set the content type, the Direct router assumes that the body should be send "as is" to the client. Usually you would use Catalyst::View::JSON to do this for you.Run the server (
# script/myapp_server.pl -r
) and access http://localhost:3000/api. You should see something like this:--- actions: Calculator: - len: 2 name: add - len: 1 name: echo type: remoting url: /api/router
This is the YAML representation of the API. As you can see, the
add
method expects two parameters and is inside theCalculator
class.If you set the content type header to
application/json
you will receive the JSON-encoded API. Try http://localhost:3000/api?content-type=application/json (see Catalyst::Controller::REST to see why this is working).A different way to access the API is to open http://localhost:3000/api/src. Open the
index
template and add this to the head area:<script type="text/javascript" src="/api/src"></script>
The API is now available from the variable
Ext.app.REMOTING_API
.Fire up your favourite browser and go to http://localhost:3000/. Open the debugger and type in the console:
Ext.Direct.addProvider(Ext.app.REMOTING_API); // This will set up the classes and methods // Ext.app.REMOTING_API is provided by /api/src Calculator.add(3, 2, function(res){alert(res)});
And watch the request and response. Next we call the
echo
method.Calculator.echo({foo: 'bar'}, function(res){console.log(res)}); // Prints {foo: 'bar'} to your browser's console
RESTful Controllers
Using CatalystX::Controller::ExtJS::REST
Run steps 1 to 6 from "FIRST STEPS" in CatalystX::ExtJS::Tutorial.
Check out CatalystX::Controller::ExtJS::REST if you are used to DBIx::Class and HTML::FormFu. To add such a controller to the Direct API, simply add the CatalystX::Controller::ExtJS::Direct role:
package MyApp::Controller::User; use Moose; extends 'CatalystX::Controller::ExtJS::REST'; with 'CatalystX::Controller::ExtJS::Direct'; 1;
CatalystX::Controller::ExtJS::REST expects a HTML::FormFu file to be located at
root/forms/user.yml
:--- elements: - name: id - name: first constraint: Required - name: last constraint: Required - name: email constraint: Required
Since the columns
first
,last
andemail
were defined asNOT NULL
columns, we have to add theRequired
constraint to them. Constraints, however, do not affectGET
andDELETE
requests. If you want a different behaviour forPOST
orPUT
requests, you can create the filesroot/forms/user_put.yml
orroot/forms/user_post.yml
accordingly. Same applies toGET
requests.While the CRUD methods (create, read, update, destroy) interact with one object only, the
list
method returns a bunch of objects. By default it uses the same configuration file as the other requests. But you can create it's own file (root/lists/user.yml
).Open http://localhost:3000/ and try:
User.list(function(res){console.log('results: ', res.results)}); User.create({first: 'Marge', last: 'Simpson'}); // this will will cause an error because 'email' is required. The // response from the server will contain an error message and the name // of the field User.create({first: 'Marge', last: 'Simpson', email:'marge@simpsons.com'}); User.list(function(res){console.log('results: ', res.results)}); User.destroy(2);
Using Catalyst::Controller::DBIC::API::RPC
Run steps 1 to 6 from "FIRST STEPS" in CatalystX::ExtJS::Tutorial.
Catalyst::Controller::DBIC::API is a convenient way to query the DBIC model via a webservice. With Ext.Direct this becomes even more convenient.
Add a new controller
lib/MyApp/Controller/User/DBIC.pm
and paste:package MyApp::Controller::User::DBIC; use Moose; extends 'Catalyst::Controller::DBIC::API::RPC'; with 'CatalystX::Controller::ExtJS::Direct'; # See Catalyst::Controller::DBIC::API for more information # on those configuration parameters __PACKAGE__->config( actions => { setup => { PathPart => 'user', Chained => '/' }, # enable Direct on these actions create => { Direct => undef, DirectArgs => 1 }, item => { Direct => undef }, update => { Direct => undef, DirectArgs => 1 }, delete => { Direct => undef }, list => { Direct => undef, DirectArgs => 1 }, }, class => 'DBIC::User', use_json_boolean => 1, create_requires => [qw(email first last)], return_object => 1, ); # Catalyst::Controller::DBIC::API cannot handle scalars and arrayrefs so # we have to add a little hack before 'deserialize' => sub { my ($self, $c) = @_; $c->req->data($c->req->data->[0]) if(ref $c->req->data eq 'ARRAY'); $c->req->data(undef) unless(ref $c->req->data); }; 1;
Access http://localhost:3000/ in your browser and open the console to play around with the DBIC API:
Ext.Direct.addProvider(Ext.app.REMOTING_API); // get all records from the model UserDBIC.list({}, function(res){console.log(res)}); UserDBIC.create({first: 'Marge', last: 'Simpson', email:'marge@simpsons.com'}); UserDBIC.item(2, function(marge){console.log(marge)}); UserDBIC.delete(2);
Try to run these commands all at once (either put them in one line or use the multi-line console in Firebug). They are now being batched and processed in just one request.
AUTHOR
Moritz Onken <onken@netcubed.de>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2014 by Moritz Onken.
This is free software, licensed under:
The (three-clause) BSD License
Module Install Instructions
To install CatalystX::ExtJS::Direct, copy and paste the appropriate command in to your terminal.
cpanm CatalystX::ExtJS::Direct
perl -MCPAN -e shell install CatalystX::ExtJS::Direct
For more information on module installation, please visit the detailed CPAN module installation guide.