ui: Maintain http headers as JSON-API meta for all API requests (#4946)

This commit is contained in:
John Cowen 2018-11-19 14:58:08 +00:00 committed by John Cowen
parent 93ebf086e0
commit 15473db84f
3 changed files with 64 additions and 2 deletions

View file

@ -13,6 +13,7 @@ export const REQUEST_DELETE = 'deleteRecord';
export const DATACENTER_QUERY_PARAM = 'dc'; export const DATACENTER_QUERY_PARAM = 'dc';
import { HEADERS_SYMBOL as HTTP_HEADERS_SYMBOL } from 'consul-ui/utils/http/consul';
export default Adapter.extend({ export default Adapter.extend({
namespace: 'v1', namespace: 'v1',
repo: service('settings'), repo: service('settings'),
@ -22,6 +23,24 @@ export default Adapter.extend({
...this._super(...arguments), ...this._super(...arguments),
}; };
}, },
handleResponse: function(status, headers, response, requestData) {
// The ember-data RESTAdapter drops the headers after this call,
// and there is no where else to get to these
// save them to response[HTTP_HEADERS_SYMBOL] for the moment
// so we can save them as meta in the serializer...
if (
(typeof response == 'object' && response.constructor == Object) ||
Array.isArray(response)
) {
// lowercase everything incase we get browser inconsistencies
const lower = {};
Object.keys(headers).forEach(function(key) {
lower[key.toLowerCase()] = headers[key];
});
response[HTTP_HEADERS_SYMBOL] = lower;
}
return this._super(status, headers, response, requestData);
},
handleBooleanResponse: function(url, response, primary, slug) { handleBooleanResponse: function(url, response, primary, slug) {
return { return {
// consider a check for a boolean, also for future me, // consider a check for a boolean, also for future me,

View file

@ -1,19 +1,59 @@
import Serializer from 'ember-data/serializers/rest'; import Serializer from 'ember-data/serializers/rest';
import { get } from '@ember/object';
import {
HEADERS_SYMBOL as HTTP_HEADERS_SYMBOL,
HEADERS_INDEX as HTTP_HEADERS_INDEX,
HEADERS_DIGEST as HTTP_HEADERS_DIGEST,
} from 'consul-ui/utils/http/consul';
export default Serializer.extend({ export default Serializer.extend({
// this could get confusing if you tried to override // this could get confusing if you tried to override
// say `normalizeQueryResponse` // say `normalizeQueryResponse`
// TODO: consider creating a method for each one of the `normalize...Response` family // TODO: consider creating a method for each one of the `normalize...Response` family
normalizeResponse: function(store, primaryModelClass, payload, id, requestType) { normalizeResponse: function(store, primaryModelClass, payload, id, requestType) {
return this._super( // Pick the meta/headers back off the payload and cleanup
// before we go through serializing
const headers = payload[HTTP_HEADERS_SYMBOL] || {};
delete payload[HTTP_HEADERS_SYMBOL];
const normalizedPayload = this.normalizePayload(payload, id, requestType);
const response = this._super(
store, store,
primaryModelClass, primaryModelClass,
{ {
[primaryModelClass.modelName]: this.normalizePayload(payload, id, requestType), [primaryModelClass.modelName]: normalizedPayload,
}, },
id, id,
requestType requestType
); );
// put the meta onto the response, here this is ok
// as JSON-API allows this and our specific data is now in
// response[primaryModelClass.modelName]
// so we aren't in danger of overwriting anything
// (which was the reason for the Symbol-like property earlier)
// use a method modelled on ember-data methods so we have the opportunity to
// do this on a per-model level
response.meta = this.normalizeMeta(
store,
primaryModelClass,
headers,
normalizedPayload,
id,
requestType
);
return response;
},
normalizeMeta: function(store, primaryModelClass, headers, payload, id, requestType) {
const meta = {
index: headers[HTTP_HEADERS_INDEX],
digest: headers[HTTP_HEADERS_DIGEST],
date: headers['date'],
};
if (requestType === 'query') {
meta.ids = payload.map(item => {
return get(item, this.primaryKey);
});
}
return meta;
}, },
normalizePayload: function(payload, id, requestType) { normalizePayload: function(payload, id, requestType) {
return payload; return payload;

View file

@ -0,0 +1,3 @@
export const HEADERS_SYMBOL = '__consul_ui_http_headers__';
export const HEADERS_INDEX = 'x-consul-index';
export const HEADERS_DIGEST = 'x-consul-contenthash';