Skip to content

Commit

Permalink
[FEATURE ds-improved-ajax] Finer control over customizing a request
Browse files Browse the repository at this point in the history
Though `ajax()` (and `ajaxOptions()`) of `DS.RESTAdapter` are marked as
private, they have been overwritten in many applications, since there is
currently no other way to customize the request.

This feature adds new public methods to `DS.RESTAdapter`, which allow to
customize the properties of a request:

- `methodForRequest` to get the HTTP verb
- `urlForRequest` to get the URL
- `headersForRequest` to get the headers
- `dataForRequest` to get the data (query params or request body)

The `params` hash passed to those methods has all the properties with
which the corresponding `find`, `createRecord`, `findQuery`, ...  call
have been invoked: store, type, snapshot(s), id(s) and query. The
`requestType` property indicates which method is requested; the possible
values are:

- `createRecord`
- `updateRecord`
- `deleteRecord`
- `query`
- `queryRecord`
- `findRecord`
- `findAll`
- `findMany`
- `findHasMany`
- `findBelongsTo`

Performing the actual AJAX request is handled by the `_makeRequest`
method, which is similar to the existing `ajax` method: it makes the
request using `jQuery.ajax` and attaches success and failure handlers.

---

Say your API handles creation of resources via PUT, this can now be
customized as follows:

``` js
// adapters/application.js
import DS from 'ember-data';

export DS.RESTAdapter.extend({
  methodForRequest: function(params) {
    if (params.requestType === 'createRecord') {
      return "PUT";
    }

    return this._super(...arguments);
  }
});
```
  • Loading branch information
pangratz committed Mar 18, 2016
1 parent e88dfed commit 41f2089
Show file tree
Hide file tree
Showing 11 changed files with 673 additions and 128 deletions.
6 changes: 6 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ entry in `config/features.json`.
`store.findRecord()` and `store.findAll()` as described in [RFC
99](https://github.com/emberjs/rfcs/pull/99)

- `ds-improved-ajax`

This feature allows to customize how a request is formed by overwriting
`methodForRequest`, `urlForRequest`, `headersForRequest` and `bodyForRequest`
in the `DS.RESTAdapter`.

- `ds-references`

Adds references as described in [RFC 57](https://github.com/emberjs/rfcs/pull/57)
Expand Down
85 changes: 76 additions & 9 deletions addon/adapters/json-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

import Ember from 'ember';
import RESTAdapter from "ember-data/adapters/rest";
import isEnabled from 'ember-data/-private/features';

/**
@class JSONAPIAdapter
@constructor
@namespace DS
@extends DS.RESTAdapter
*/
export default RESTAdapter.extend({
var JSONAPIAdapter = RESTAdapter.extend({
defaultSerializer: '-json-api',

/**
Expand Down Expand Up @@ -98,8 +99,12 @@ export default RESTAdapter.extend({
@return {Promise} promise
*/
findMany(store, type, ids, snapshots) {
var url = this.buildURL(type.modelName, ids, snapshots, 'findMany');
return this.ajax(url, 'GET', { data: { filter: { id: ids.join(',') } } });
if (isEnabled('ds-improved-ajax')) {
return this._super(...arguments);
} else {
var url = this.buildURL(type.modelName, ids, snapshots, 'findMany');
return this.ajax(url, 'GET', { data: { filter: { id: ids.join(',') } } });
}
},

/**
Expand All @@ -121,14 +126,76 @@ export default RESTAdapter.extend({
@return {Promise} promise
*/
updateRecord(store, type, snapshot) {
var data = {};
var serializer = store.serializerFor(type.modelName);
if (isEnabled('ds-improved-ajax')) {
return this._super(...arguments);
} else {
var data = {};
var serializer = store.serializerFor(type.modelName);

serializer.serializeIntoHash(data, type, snapshot, { includeId: true });
serializer.serializeIntoHash(data, type, snapshot, { includeId: true });

var id = snapshot.id;
var url = this.buildURL(type.modelName, id, snapshot, 'updateRecord');
var id = snapshot.id;
var url = this.buildURL(type.modelName, id, snapshot, 'updateRecord');

return this.ajax(url, 'PATCH', { data: data });
return this.ajax(url, 'PATCH', { data: data });
}
}
});

if (isEnabled('ds-improved-ajax')) {

JSONAPIAdapter.reopen({

methodForRequest(params) {
if (params.requestType === 'updateRecord') {
return 'PATCH';
}

return this._super(...arguments);
},

dataForRequest(params) {
const { requestType, ids } = params;

if (requestType === 'findMany') {
return {
filter: { id: ids.join(',') }
};
}

if (requestType === 'updateRecord') {
const { store, type, snapshot } = params;
const data = {};
const serializer = store.serializerFor(type.modelName);

serializer.serializeIntoHash(data, type, snapshot, { includeId: true });

return data;
}

return this._super(...arguments);
},

headersForRequest() {
const headers = this._super(...arguments) || {};

headers['Accept'] = 'application/vnd.api+json';

return headers;
},

_requestToJQueryAjaxHash() {
const hash = this._super(...arguments);

if (hash.contentType) {
hash.contentType = 'application/vnd.api+json';
}

return hash;
}

});

}

export default JSONAPIAdapter;
Loading

0 comments on commit 41f2089

Please sign in to comment.