[Catalyst-commits] r7202 - in trunk/examples/CatalystAdvent/root/2007: . pen

jshirley at dev.catalyst.perl.org jshirley at dev.catalyst.perl.org
Sun Dec 2 17:28:22 GMT 2007


Author: jshirley
Date: 2007-12-02 17:28:21 +0000 (Sun, 02 Dec 2007)
New Revision: 7202

Added:
   trunk/examples/CatalystAdvent/root/2007/2.pod
Removed:
   trunk/examples/CatalystAdvent/root/2007/pen/2.pod
Log:
Publishing day 2

Copied: trunk/examples/CatalystAdvent/root/2007/2.pod (from rev 7201, trunk/examples/CatalystAdvent/root/2007/pen/2.pod)
===================================================================
--- trunk/examples/CatalystAdvent/root/2007/2.pod	                        (rev 0)
+++ trunk/examples/CatalystAdvent/root/2007/2.pod	2007-12-02 17:28:21 UTC (rev 7202)
@@ -0,0 +1,353 @@
+=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.  This is not a 
+copy and paste article, but explains the general concepts as a read-along to reading the
+source of the example application.
+
+=head2 Start Here First: Understanding REST
+
+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: Using the Source
+
+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/RestYUI
+
+This is a fully functional application that uses REST webservices instead of the
+traditional method of form submission and posting.  While this isn't an ideal use of
+REST, and it doesn't give you anything over a non-JavaScript based form, it should help
+people think about things a little different and show the power of a framework that can
+use any view, not just HTML, to represent objects.
+
+This article talks about building the core pieces, but there are many other important
+points in the example application that are not covered specifically in the article.  Please
+check out the source above, run the application and read the source as you read this
+article.  
+
+=head1 Why use JavaScript?
+
+The big question that comes along when working with REST in the browser is why do you have
+to use JavaScript.  The reason why we're required to use JavaScript for a full REST service
+is because the vocabulary that a browser speaks natively is limited to only two verbs: GET
+and PoST.
+
+However, when using the C<XmlHttpRequest> JavaScript object that is available in all Grade
+A browsers the vocabulary is extended to support PUT, DELETE and HEAD and many others.
+
+With this, you can write a web application that is also a web service, with very little
+redundant code.  Additionally, the tests can test the data and separate tests can test
+the HTML rendering.  This makes things much less tedious, and the tests more accurate.
+
+With Selenium testing the JavaScript, you can have full end-to-end testing with very little
+pain.  To me, we're finally at a point in browser development where the question is why not
+use JavaScript.
+
+=head2 Connecting to REST
+
+The general idea of REST is getting what you ask for, in the format you want.  In the
+simplest form, an C<XmlHttpRequest> isn't enough to talk to a REST webservice.  There are a
+few major points that come together to make everything work:
+
+=over
+
+=item Content Type
+
+Because YUI assumes you're working with a brain-dead framework that can't
+support wonderful things like REST, you have to map the default content-type
+(or dig into YUI and setup different content type headers, but this is quite
+a bit of work).  In the REST controller, assigning this content type to 
+serialization format is a piece of cake:
+
+ __PACKAGE__->config(
+    # Set the default serialization to JSON
+    'default' => 'JSON',
+    'map' => {
+        # Remap x-www-form-urlencoded to use JSON for serialization
+        'application/x-www-form-urlencoded' => 'JSON',
+    },
+ );
+
+YUI will also not set the default content type header to a useful value, so you have to
+do that in the JavaScript.  This is covered later in detail.
+
+=item Request Method
+
+The request method is the verb.  This means you are GETting a resource, PUTting a new
+resource in the system, POSTing an update to an existing resource or DELETEing something.
+
+Luckily, XmlHttpRequest and YUI supports this just fine without any additional tweaking.
+
+=item Data Serialization
+
+The Content-Type not only specifies how you want the data back, but it specifies how
+you are sending data.  In the context of a PUT or POST, any data you send has to match
+the Content-Type provided.  So if you send a Content-type header of 'text/x-json', the
+data has to be in JSON.  There are a ton of serialization formats available, so pick
+what works best for you in each application.
+
+If you're working with a JavaScript-based interface, I prefer JSON.  If I'm doing command
+line interaction, I like serialization in YAML.  The same resource can handle multiple
+serialization formats, just change the Content-type!
+
+=back
+
+=head2 Starting the Catalyst Application
+
+We're taking last year's AdventREST example app and slightly modifying it to
+add support for YUI.
+
+So, to get started you can check out that application from subversion by doing:
+ 
+ svn co http://dev.catalystframework.org/repos/Catalyst/trunk/examples/AdventREST
+
+Or check out the completed RestYUI application.
+
+The only fundamental change to the application is adding the Template Toolkit
+view:
+
+ script/adventrest_create.pl view TT TT
+
+Also, we have to grab the static files for YUI itself.  As of writing this,
+version 2.3.1 is available from L<http://sourceforge.net/project/downloading.php?group_id=165715&filename=yui_2.3.1.zip>.  Check the latest version at
+L<http://developer.yahoo.com/yui/>
+
+After extracting the files from the zip archive, just copy over the .js files to
+the root/static directory.  My preferred method is to do this:
+
+ cd MyApp
+ mkdir root/static/yui
+ cd /where/you/unpacked/yui/build
+ for i in *; do cp $i/$i.js $i/$i-beta.js /path/to/MyApp/root/static/yui; done
+
+That will copy all the non-minimized (but not debug versions) and beta JS files
+into your static/yui path, so you can reference them with an easy URI:
+ C</static/yui/yahoo.js>
+
+The other files that are very useful are the "sam" CSS and image files.  For
+the datatable, we're going to use C<sam/datatable.css> and a few other images:
+
+=over
+
+=item sprite.png
+
+=item dt-arrow-dn.png
+
+=item dt-arrow-up.png
+
+=back
+
+Those will make the DataTable look nice and stylish.  If you want to expand more
+on the YUI styles then the buttons, containers and other layouts are a great
+asset provided by Yahoo.
+
+=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.
+
+We'll create a simple template off of the index action in C<Root.pm>, so
+create this action in Root.pm:
+
+ sub index : Private {
+     my ( $self, $c ) = @_;
+     $c->forward( $c->view('TT') );
+ }
+
+That will just direct the action for "/" to go to TT, and render an "index.tt"
+template.
+
+The C<index.tt> file is pretty basic, and after the HTML tags this is the crux
+of what gets the job done:
+
+    /* Create the YAHOO.util.DataSource object, the parameter is the
+       URI to your REST service
+    */
+    this.myDataSource = new YAHOO.util.DataSource("[%
+         c.uri_for( c.controller('User').action_for('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"
+            }
+        );
+
+=head1 Adding REST PUT and POST Methods via YUI
+
+The fundamental difference between a PUT and POST is a PUT creates a new resource and
+POST updates an existing resource.  In the original advent article, the PUT and POST
+articles were aliased and therefore provide identical functionality.  We're not going to
+change this, because for the purposes of this article it doesn't matter.  YUI will
+respect whatever method provided in the C<asyncRequest> call.  So if you want to do a
+PUT, the call looks like:
+
+    var request = YAHOO.util.Connect.asyncRequest(
+        'PUT',
+        uri, callback, json_data
+    );
+
+It's a good idea to read the overview and some examples of how to use asyncRequest, but
+the usage is very simple.  That is really all that is necessary to trigger a REST call
+in YUI, but you have to watch the content type.  By default, YUI will not set the
+proper content type, and since JSON is by far the easiest serialization method to use
+in JavaScript, we're going to use that.  YUI fortunately has an easy method for changing
+the content type, but it isn't a well-named method and you have to be careful because it
+sets the content type on subsequent calls:
+
+    YAHOO.util.Connect.setDefaultPostHeader('text/x-json');
+
+Adding that line before any C<asyncRequest> calls will ensure you are sending the
+right content type header, and won't cause the REST service any confusion.  The next
+step is actually encoding the JSON data from the form.
+
+=head2 JSON Parsing and Encoding in JavaScript
+
+The C<json2.js> JSON stringifier and parser is used in this article and is available from
+L<http://www.JSON.org/js.html>.  It is public domain, and works very well.
+
+=head2 From Form to JSON to REST
+
+Given a form object, as what is declared in the C<root/user/single_user.tt> file, and
+hijack the normal submit mechanisms to enable a REST POST or PUT to a backend webservice
+is just a simple few lines of JavaScript:
+
+    /* Setup the listener when the form is submitted: */
+    YAHOO.util.Event.addListener(form, "submit", function(e) {
+        /* Cancel the default submit event.
+           You can get creative here for graceful fallbacks, think about it!
+        */
+        YAHOO.util.Event.preventDefault(e);
+        /* Start a timeout to encapsulate the REST call */
+        window.setTimeout(function() {
+            /* What URI are we going to POST or PUT to?  Ourselves, in this case */
+            var uri  = '[% c.req.uri %]';
+
+            /* The actual data structure, it still is just JavaScript at this point.
+               Keep in mind there are better ways to take a form and translate it into
+               JSON, but being explicit never killed anybody
+            */
+            var data = {
+                user_id:     form['user_id'].value,
+                fullname:    form['fullname'].value,
+                description: form['description'].value
+            };
+            /* Set the content-type to text/x-json, otherwise things will break! */ 
+            YAHOO.util.Connect.setDefaultPostHeader('text/x-json');
+            /* The actual call, this bit makes the HTTP call */
+            var request = YAHOO.util.Connect.asyncRequest(
+                '[% method %]',
+                uri,
+                /* Callback should contain a success and failure method, read the
+                   YUI asyncRequest docs! */
+                callback,
+                /* Stringify our data structure into JSON, this is sent in the HTTP BODY */
+                JSON.stringify(data)
+            );
+        }, 200);
+    });
+
+That's it, with a lot of comments!  This will send a PUT or POST request to the backend
+service with the form data encoded in JSON.  You're not limited to PUT or POST methods,
+you can also use DELETE, HEAD and any other method defined in the RFC.
+
+To see the full page, check out C<root/user/single_user.tt> in the RestYUI example.
+
+=head1 The State of (un)REST in the Browser World
+
+Beware, that not all browsers support every method so YUI and REST is not guaranteed to
+work on every browser and every platform.  It's up to the browser developers to decide to
+support full specifications and I'm happy to report that most browsers do in this context,
+including both Internet Explorer 6.x and 7.
+
+=head1 AUTHOR
+
+J. Shirley wrote the YUI based portions, with the original 2006 REST article
+being written by Adam Jacob.
+
+Adam Jacob also wrote the Catalyst::Action::REST module, which is the foundation
+to all of this.
+
+=cut
+

Deleted: trunk/examples/CatalystAdvent/root/2007/pen/2.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2007/pen/2.pod	2007-12-02 17:27:10 UTC (rev 7201)
+++ trunk/examples/CatalystAdvent/root/2007/pen/2.pod	2007-12-02 17:28:21 UTC (rev 7202)
@@ -1,353 +0,0 @@
-=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.  This is not a 
-copy and paste article, but explains the general concepts as a read-along to reading the
-source of the example application.
-
-=head2 Start Here First: Understanding REST
-
-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: Using the Source
-
-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/RestYUI
-
-This is a fully functional application that uses REST webservices instead of the
-traditional method of form submission and posting.  While this isn't an ideal use of
-REST, and it doesn't give you anything over a non-JavaScript based form, it should help
-people think about things a little different and show the power of a framework that can
-use any view, not just HTML, to represent objects.
-
-This article talks about building the core pieces, but there are many other important
-points in the example application that are not covered specifically in the article.  Please
-check out the source above, run the application and read the source as you read this
-article.  
-
-=head1 Why use JavaScript?
-
-The big question that comes along when working with REST in the browser is why do you have
-to use JavaScript.  The reason why we're required to use JavaScript for a full REST service
-is because the vocabulary that a browser speaks natively is limited to only two verbs: GET
-and PoST.
-
-However, when using the C<XmlHttpRequest> JavaScript object that is available in all Grade
-A browsers the vocabulary is extended to support PUT, DELETE and HEAD and many others.
-
-With this, you can write a web application that is also a web service, with very little
-redundant code.  Additionally, the tests can test the data and separate tests can test
-the HTML rendering.  This makes things much less tedious, and the tests more accurate.
-
-With Selenium testing the JavaScript, you can have full end-to-end testing with very little
-pain.  To me, we're finally at a point in browser development where the question is why not
-use JavaScript.
-
-=head2 Connecting to REST
-
-The general idea of REST is getting what you ask for, in the format you want.  In the
-simplest form, an C<XmlHttpRequest> isn't enough to talk to a REST webservice.  There are a
-few major points that come together to make everything work:
-
-=over
-
-=item Content Type
-
-Because YUI assumes you're working with a brain-dead framework that can't
-support wonderful things like REST, you have to map the default content-type
-(or dig into YUI and setup different content type headers, but this is quite
-a bit of work).  In the REST controller, assigning this content type to 
-serialization format is a piece of cake:
-
- __PACKAGE__->config(
-    # Set the default serialization to JSON
-    'default' => 'JSON',
-    'map' => {
-        # Remap x-www-form-urlencoded to use JSON for serialization
-        'application/x-www-form-urlencoded' => 'JSON',
-    },
- );
-
-YUI will also not set the default content type header to a useful value, so you have to
-do that in the JavaScript.  This is covered later in detail.
-
-=item Request Method
-
-The request method is the verb.  This means you are GETting a resource, PUTting a new
-resource in the system, POSTing an update to an existing resource or DELETEing something.
-
-Luckily, XmlHttpRequest and YUI supports this just fine without any additional tweaking.
-
-=item Data Serialization
-
-The Content-Type not only specifies how you want the data back, but it specifies how
-you are sending data.  In the context of a PUT or POST, any data you send has to match
-the Content-Type provided.  So if you send a Content-type header of 'text/x-json', the
-data has to be in JSON.  There are a ton of serialization formats available, so pick
-what works best for you in each application.
-
-If you're working with a JavaScript-based interface, I prefer JSON.  If I'm doing command
-line interaction, I like serialization in YAML.  The same resource can handle multiple
-serialization formats, just change the Content-type!
-
-=back
-
-=head2 Starting the Catalyst Application
-
-We're taking last year's AdventREST example app and slightly modifying it to
-add support for YUI.
-
-So, to get started you can check out that application from subversion by doing:
- 
- svn co http://dev.catalystframework.org/repos/Catalyst/trunk/examples/AdventREST
-
-Or check out the completed RestYUI application.
-
-The only fundamental change to the application is adding the Template Toolkit
-view:
-
- script/adventrest_create.pl view TT TT
-
-Also, we have to grab the static files for YUI itself.  As of writing this,
-version 2.3.1 is available from L<http://sourceforge.net/project/downloading.php?group_id=165715&filename=yui_2.3.1.zip>.  Check the latest version at
-L<http://developer.yahoo.com/yui/>
-
-After extracting the files from the zip archive, just copy over the .js files to
-the root/static directory.  My preferred method is to do this:
-
- cd MyApp
- mkdir root/static/yui
- cd /where/you/unpacked/yui/build
- for i in *; do cp $i/$i.js $i/$i-beta.js /path/to/MyApp/root/static/yui; done
-
-That will copy all the non-minimized (but not debug versions) and beta JS files
-into your static/yui path, so you can reference them with an easy URI:
- C</static/yui/yahoo.js>
-
-The other files that are very useful are the "sam" CSS and image files.  For
-the datatable, we're going to use C<sam/datatable.css> and a few other images:
-
-=over
-
-=item sprite.png
-
-=item dt-arrow-dn.png
-
-=item dt-arrow-up.png
-
-=back
-
-Those will make the DataTable look nice and stylish.  If you want to expand more
-on the YUI styles then the buttons, containers and other layouts are a great
-asset provided by Yahoo.
-
-=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.
-
-We'll create a simple template off of the index action in C<Root.pm>, so
-create this action in Root.pm:
-
- sub index : Private {
-     my ( $self, $c ) = @_;
-     $c->forward( $c->view('TT') );
- }
-
-That will just direct the action for "/" to go to TT, and render an "index.tt"
-template.
-
-The C<index.tt> file is pretty basic, and after the HTML tags this is the crux
-of what gets the job done:
-
-    /* Create the YAHOO.util.DataSource object, the parameter is the
-       URI to your REST service
-    */
-    this.myDataSource = new YAHOO.util.DataSource("[%
-         c.uri_for( c.controller('User').action_for('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"
-            }
-        );
-
-=head1 Adding REST PUT and POST Methods via YUI
-
-The fundamental difference between a PUT and POST is a PUT creates a new resource and
-POST updates an existing resource.  In the original advent article, the PUT and POST
-articles were aliased and therefore provide identical functionality.  We're not going to
-change this, because for the purposes of this article it doesn't matter.  YUI will
-respect whatever method provided in the C<asyncRequest> call.  So if you want to do a
-PUT, the call looks like:
-
-    var request = YAHOO.util.Connect.asyncRequest(
-        'PUT',
-        uri, callback, json_data
-    );
-
-It's a good idea to read the overview and some examples of how to use asyncRequest, but
-the usage is very simple.  That is really all that is necessary to trigger a REST call
-in YUI, but you have to watch the content type.  By default, YUI will not set the
-proper content type, and since JSON is by far the easiest serialization method to use
-in JavaScript, we're going to use that.  YUI fortunately has an easy method for changing
-the content type, but it isn't a well-named method and you have to be careful because it
-sets the content type on subsequent calls:
-
-    YAHOO.util.Connect.setDefaultPostHeader('text/x-json');
-
-Adding that line before any C<asyncRequest> calls will ensure you are sending the
-right content type header, and won't cause the REST service any confusion.  The next
-step is actually encoding the JSON data from the form.
-
-=head2 JSON Parsing and Encoding in JavaScript
-
-The C<json2.js> JSON stringifier and parser is used in this article and is available from
-L<http://www.JSON.org/js.html>.  It is public domain, and works very well.
-
-=head2 From Form to JSON to REST
-
-Given a form object, as what is declared in the C<root/user/single_user.tt> file, and
-hijack the normal submit mechanisms to enable a REST POST or PUT to a backend webservice
-is just a simple few lines of JavaScript:
-
-    /* Setup the listener when the form is submitted: */
-    YAHOO.util.Event.addListener(form, "submit", function(e) {
-        /* Cancel the default submit event.
-           You can get creative here for graceful fallbacks, think about it!
-        */
-        YAHOO.util.Event.preventDefault(e);
-        /* Start a timeout to encapsulate the REST call */
-        window.setTimeout(function() {
-            /* What URI are we going to POST or PUT to?  Ourselves, in this case */
-            var uri  = '[% c.req.uri %]';
-
-            /* The actual data structure, it still is just JavaScript at this point.
-               Keep in mind there are better ways to take a form and translate it into
-               JSON, but being explicit never killed anybody
-            */
-            var data = {
-                user_id:     form['user_id'].value,
-                fullname:    form['fullname'].value,
-                description: form['description'].value
-            };
-            /* Set the content-type to text/x-json, otherwise things will break! */ 
-            YAHOO.util.Connect.setDefaultPostHeader('text/x-json');
-            /* The actual call, this bit makes the HTTP call */
-            var request = YAHOO.util.Connect.asyncRequest(
-                '[% method %]',
-                uri,
-                /* Callback should contain a success and failure method, read the
-                   YUI asyncRequest docs! */
-                callback,
-                /* Stringify our data structure into JSON, this is sent in the HTTP BODY */
-                JSON.stringify(data)
-            );
-        }, 200);
-    });
-
-That's it, with a lot of comments!  This will send a PUT or POST request to the backend
-service with the form data encoded in JSON.  You're not limited to PUT or POST methods,
-you can also use DELETE, HEAD and any other method defined in the RFC.
-
-To see the full page, check out C<root/user/single_user.tt> in the RestYUI example.
-
-=head1 The State of (un)REST in the Browser World
-
-Beware, that not all browsers support every method so YUI and REST is not guaranteed to
-work on every browser and every platform.  It's up to the browser developers to decide to
-support full specifications and I'm happy to report that most browsers do in this context,
-including both Internet Explorer 6.x and 7.
-
-=head1 AUTHOR
-
-J. Shirley wrote the YUI based portions, with the original 2006 REST article
-being written by Adam Jacob.
-
-Adam Jacob also wrote the Catalyst::Action::REST module, which is the foundation
-to all of this.
-
-=cut
-




More information about the Catalyst-commits mailing list