[Catalyst-commits] r7157 - trunk/examples/CatalystAdvent/root/2007

jshirley at dev.catalyst.perl.org jshirley at dev.catalyst.perl.org
Fri Nov 23 00:07:58 GMT 2007


Author: jshirley
Date: 2007-11-23 00:07:58 +0000 (Fri, 23 Nov 2007)
New Revision: 7157

Modified:
   trunk/examples/CatalystAdvent/root/2007/3.pod
Log:
Initial dprogress of day 3

Modified: trunk/examples/CatalystAdvent/root/2007/3.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2007/3.pod	2007-11-22 22:06:37 UTC (rev 7156)
+++ trunk/examples/CatalystAdvent/root/2007/3.pod	2007-11-23 00:07:58 UTC (rev 7157)
@@ -1,5 +1,146 @@
 =head1 Get more REST - Using YUI and JavaScript for REST
 
+Today, we'll look into building a fully capable REST client in YUI that allows
+record creation, retrieving, updating and deletion (CRUD) as well as searching.
+
+=head2 Start Here First
+
+To make the most of this article, it is important to not only understand the
+basic idea of REST but to also see how it works within Catalyst.
+
+To start out understanding REST, read the excellent article by Ryan Tomayko 
+L<http://tomayko.com/articles/2004/12/12/rest-to-my-wife>, about explaining
+REST in simple terms that a non technical person is able to understand.  It will
+help a technical person understand it even more.
+
+Up next is to get a good understanding for how REST works inside of Catalyst,
+using Adam Jacob's excellent L<Catalyst::Action::REST> package.  The best way
+to get up to speed is to review Day 9 from the 2006 Advent Calendar, at
+L<http://www.catalystframework.org/calendar/2006/9.pod>.
+
+=head2 Following Along
+
+The examples that are listed here are available from the Catalyst subversion
+repository, available via:
+
+ svn co http://dev.catalystframework.org/repos/Catalyst/trunk/examples/CatalystREST-YUI
+
+It is a good idea to check out the sources of the sample application to better
+follow along with the examples.  Included is the necessary YUI javascript files
+to enhance this application as you go.
+
+=head2 Why use JavaScript?
+
+The reason why we're required to use JavaScript for a full REST service is
+because of the limited vocabulary that a browser coupled with plain HTML is
+allowed to speak.  The browser will only ever send GET and POST requests in
+response to user interaction with an HTML document.  However, when using the
+C<XmlHttpRequest> method that is a standard in all Grade A browsers the 
+vocabulary is extended to support PUT, DELETE and HEAD.
+
+=head2 The Connection to REST
+
+REST is based off of getting what you ask for.  In the simplest form, an
+C<XmlHttpRequest> isn't enough to talk to a REST webservice.  There are a few
+major components that fit together to make everything work:
+
+=over
+
+=item Content Type
+
+=item Request Method
+
+=item 
+
+=back
+
+=head2 Preparing the REST WebService
+
+To gain access to the REST services, we'll be accessing both the C<list> and the
+C<item> actions.  The list is going to be pulled by using a customized YUI
+DataSource object.
+
+This will ask the REST service for a list of our people objects, and in a simple
+form is nothing more than a L<DBIx::Class> search:
+
+   sub user_list_GET {
+       my ( $self, $c ) = @_;
+
+       my %user_list;
+       my $user_rs = $c->model('DB::User')->search;
+       while ( my $user_row = $user_rs->next ) {
+           $user_list{ $user_row->user_id } =
+             $c->uri_for( '/user/' . $user_row->user_id )->as_string;
+       }
+       $self->status_ok( $c, entity => \%user_list );
+   }
+
+That is from the original REST article, and to make the most of the list we're
+going to enhance the listing to provide some additional meta information that 
+enhances the webservice with features such as pagination and other contextual
+information.  We'll add in pagination with a CGI parameter "page" and a param
+for the number of items per page called "per_page"
+
+   sub user_list_GET {
+       my ( $self, $c ) = @_;
+       my $page     = $c->req->params->{page} || 1;
+       my $per_page = $c->req->params->{per_page} || 10;
+
+       # We'll use an array now:
+       my @user_list;
+       my $rs = $c->model('DB::User')
+           ->search(undef, { rows => $per_page })->page( $page );
+       while ( my $user_row = $rs->next ) {
+           push @user_list, {
+               $user_row->get_columns,
+               uri => $c->uri_for( '/user/' . $user_row->user_id )->as_string
+           };
+       }
+
+       $self->status_ok( $c, entity => {
+           result_set => {
+               totalResultsAvailable => $rs->pager->total_entries,
+               totalResultsReturned  => $rs->pager->entries_on_this_page,
+               firstResultPosition   => $rs->pager->current_page
+               result => [ @user_list ]
+           ;}
+       });
+   };
+
+So now we have a serialized structure that looks like this in JSON:
+
+=head2 Connecting with YUI
+
+After the webservice is up, it is time to setup the Yahoo DataSource object:
+
+    /* Create the YAHOO.util.DataSource object, the parameter is the
+       URI to your REST service
+    */
+    this.myDataSource = new YAHOO.util.DataSource("/rest/user_list?");
+    this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
+    this.myDataSource.connXhrMode = "queueRequests";
+    this.myDataSource.responseSchema = {
+    	resultsList: "result_set.result",
+        /* We have to define the fields for usage elsewhere */
+        fields: [
+            "pk1", "token", "default_lang", "languages",
+            "url", "t_created", "t_updated", "actions"
+        ]
+     };
+
+After this, we have a functional DataSource object that can be tied into a
+DataTable:
+
+        myDataTable = new YAHOO.widget.DataTable(
+            "kb_list", myColumnDefs,
+            this.myDataSource, {
+                /* The initialRequest is appended to the URI to set params */
+                initialRequest: "page=1&content-type=text/x-json"
+            }
+        );
+
+=cut
+
 =head1 AUTHOR
 
 J. Shirley




More information about the Catalyst-commits mailing list