Search code examples
javascriptamplifyjs

Amplify.js - CRUD-like urls


I am using amplify.request, and I would like to have CRUD-like URLs when sending data to and from the server. Here is an example:

Defining the resource

resources = {
"document_create"           : ['/d/crud/',           "POST"],
"document_read"             : ['/d/crud/{id}',       "GET"],
"document_update"           : ['/d/crud/{id}',       "PUT"],
"document_delete"           : ['/d/crud/{id}',       "DELETE"]
};

$.each(resources, function (resource, settings) {
  definition = {
    url     : settings[0],
    type    : settings[1],
    dataType: "json",  // what comes back
    decoder : 'jsend',
    contentType: 'application/json' // what goes there
  };

  amplify.request.define(resource, "ajax", definition);
});

Employing the resource

function make_request(resource, params, success_cb, error_cb) {
 if (this.is_post(resource)) {
   // this.is_post is a test, defined elsewhere, to see if this is a POST request
   params = JSON.stringify(params);
 }

 amplify.request(
   resourceId: resource
   data: params
   success: success_cb
   error: error_cb
 );
}

This works fine for create and read and `delete, like-so:

make_request('document_delete', {id: 1}, cb)

However, for update, since the content is being passed as JSON, the URL substitution does not occur as intended.

Is there a way to take advantage of the URL substitution for {id} in the above scheme?

The only alternative I can think of is to pass the data to the server URL-encoded. Unfortunately this is somewhat problematic, and I would prefer to be able to retain the use of CRUD-like URLs and saving with JSON formatted data, if that is possible.

Thoughts would be appreciated.


Solution

  • You could define your own request type, or you could just listen for request.ajax.preprocess and do your JSON.stringify there – which is after the URL substitution has occurred.

    The is_post is presumably the same code you have now, just put in a different place. It's not a magic function :)

     amplify.subscribe( "request.ajax.preprocess", function( defnSettings, settings, ajaxSettings ) {
        if ( is_post( defnSettings.resourceId ) ) {
             // This will still include the variable that matches the URL substitution:
             var _settings = $.extend( true, {}, defnSettings.data, settings.data, ajaxSettings.data );
             ajaxSettings.data = JSON.stringify( _settings );
        }
     });
    

    Your make_request would no longer stringify:

    function make_request(resource, params, success_cb, error_cb) {
     amplify.request(
       resourceId: resource
       data: params
       success: success_cb
       error: error_cb
     );
    }
    

    Then your request can be run as normal:

    make_request('document_update', {id: 1, title: "New Title" }, cb)
    

    Important: the way I wrote the preprocess call, it will not remove the id even though it matched the URL (Amplify would normally delete the matched key). If you want it to remove the id from the stringified JSON, replace the _settings assignment with this:

    _settings = ajaxSettings.data;