Amplify.js - URL-адреса, подобные CRUD

Я использую amplify.request, и я хотел бы иметь URL-адреса, подобные CRUD, при отправке данных на сервер и с сервера. Вот пример:

Определение ресурса

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);
});

Использование ресурса

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
 );
}

Это отлично работает для create и read и `delete, like-so:

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

Однако, для update, поскольку содержимое передается как JSON, замена URL не выполняется так, как предполагалось.

Есть ли способ использовать замену URL для {id} в приведенной выше схеме?

Единственная альтернатива, о которой я могу думать, - передать данные на URL-адрес сервера. К сожалению, это несколько проблематично, и я предпочел бы сохранить возможность использования CRUD-подобных URL-адресов и сохранения с форматированными данными JSON, если это возможно.

Мысли будут оценены.

Ответ 1

Вы можете определить свой собственный тип запроса или просто прослушать request.ajax.preprocess и сделать свой JSON.stringify там, где после замены URL.

is_post - это, по-видимому, тот же самый код, который у вас есть сейчас, просто в другом месте. Это не волшебная функция:)

 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 );
    }
 });

Ваш make_request больше не будет stringify:

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

Затем ваш запрос может быть запущен как обычно:

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

Важно:, как я написал вызов препроцесса, он не удалит id, даже если он соответствует URL (обычно Amplify удаляет совпадающий ключ). Если вы хотите удалить id из строкового JSON, замените назначение _settings следующим образом:

_settings = ajaxSettings.data;

Ответ 2

Как и для Amplify 1.1.0, при определении ресурсов существует опция dataMap. Если вы передадите функцию вместо хеш-объекта, функция усиления будет вызывать эту функцию с необработанными данными, переданными в запрос.

В этом примере я передаю JSON.stringify опции dataMap.

amplify.request.define("paqueteput", "ajax", {
    url: "/api/paquetes/{id}",
    dataType: "json",
    type: "PUT",
    contentType: "application/json; charset=utf-8",
    dataMap: JSON.stringify
});


// later we pass a raw object that gets stringified to JSON
var savePaquete = function(paquete, cb) {
    amplify.request({
         resourceId: "paqueteput",
         data: paquete,
         success: cb.sucess,
         error: cb.error
    });
};

Единственное, что мне не очень нравится, это усиление удаления ключей, отображаемых в URL-адресе из вашего объекта данных. В этом случае свойство id удаляется из конечного JSON, хотя оно присутствует в URL-адресе.

Должна быть опция усиления для контроля этого поведения!