chore: add support for prefix and suffix with enhanced API

This commit is contained in:
Randall Morey committed 2020-07-15 15:52:21 -04:00
1 parent 3b37c0f92a
commit 89b736744f
3 files changed
+137 -1

No files matched your search

+4 -1
View File
@@ -1,4 +1,5 @@
import RESTAdapter from '@ember-data/adapter/rest';
import AdapterBuildURLMixin from '../mixins/adapter-build-url';
import config from 'ember-get-config';
import { get } from '@ember/object';
import { InvalidError } from '@ember-data/adapter/error';
@@ -36,7 +37,9 @@ function prenormalizeArrayResponse(response) {
return payloadIsBlank(response) ? {items: []} : response;
}
export default class ApplicationAdapter extends RESTAdapter {
export default class ApplicationAdapter extends RESTAdapter.extend(
AdapterBuildURLMixin
) {
// =attributes
/**
@@ -0,0 +1,78 @@
import Mixin from '@ember/object/mixin';
import { get } from '@ember/object';
/**
* Overrides URL-building methods in an adpater for greater flexibility.
* Specifically enhances calls to `urlPrefix` with `modelName`, `id`, and
* `snapshot`, which aren't normally passed. And adds support for a
* `urlSuffix` method, the return value of which is appended to the end of
* a generated URL.
*
* While this mixin provides an enhanced API, it doesn't actually change the
* way URLs are generated by default. Override methods in the adapter that
* uses this mixin to alter generated URLs.
*/
export default Mixin.create({
// =methods
/**
* This override behaves identically to the default method by default.
* It exists only to document the additional paramters to the method.
* @override
* @param {string} path
* @param {string} parentURL
* @param {string} modelName
* @param {string} id
* @param {object} snapshot
* @return {string} urlPrefix
*/
urlPrefix(/* path, parentURL, modelName, id, snapshot */) {
// What's this super syntax?
// Ember mixins are still based on the older Ember Object, rather than
// native ES classes. Thus we have to call super in this strange way.
// https://blog.emberjs.com/2019/01/26/emberjs-native-class-update-2019-edition.html
return this._super(...arguments);
},
/**
* Generates a string to be appended to a URL. Empty string by default.
* @param {string} modelName
* @param {string} id
* @param {?object} snapshot
* @return {string}
*/
urlSuffix(/* modelName, id, snapshot */) {
return '';
},
/**
* Overrides the default `_buildURL` with a nearly identical version.
* This method simply passes arguments into the `urlPrefix` method for
* convenience, where by default it receives no arguments.
*
* Adds a suffix, generated by the `urlSuffix` method, to the URL.
* @override
* @param {String} modelName
* @param {String} id
* @return {String} url
*/
_buildURL(modelName, id, snapshot) {
let path;
let url = [];
const host = get(this, 'host');
const prefix = this.urlPrefix(null, null, modelName, id, snapshot);
const suffix = this.urlSuffix(modelName, id, snapshot);
if (modelName) {
path = this.pathForType(modelName);
if (path) url.push(path);
}
if (id) url.push(encodeURIComponent(id));
if (prefix) url.unshift(prefix);
url = url.join('/');
if (!host && url && url.charAt(0) !== '/') url = '/' + url;
return `${url}${suffix}`;
}
});
@@ -0,0 +1,55 @@
import RESTAdapter from '@ember-data/adapter/rest';
import AdapterBuildURLMixin from 'api/mixins/adapter-build-url';
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Mixin | build-url', function(hooks) {
setupTest(hooks);
test('it does not interfere with basic URLs', function (assert) {
assert.expect(1);
const Adapter = RESTAdapter.extend(AdapterBuildURLMixin);
this.owner.register('adapter:adapter', Adapter);
const adapter = this.owner.lookup('adapter:adapter');
const url = adapter._buildURL('model', 1);
assert.equal(url, '/models/1');
});
test('it does not interfere with namespaced URLs', function (assert) {
assert.expect(1);
const Adapter = RESTAdapter.extend(AdapterBuildURLMixin, {
namespace: 'api/v1'
});
this.owner.register('adapter:adapter', Adapter);
const adapter = this.owner.lookup('adapter:adapter');
const url = adapter._buildURL('model', 1);
assert.equal(url, '/api/v1/models/1');
});
test('it can prepend a prefix', function (assert) {
assert.expect(1);
const Adapter = RESTAdapter.extend(AdapterBuildURLMixin, {
urlPrefix() {
return '/foo/bars'
}
});
this.owner.register('adapter:adapter', Adapter);
const adapter = this.owner.lookup('adapter:adapter');
const url = adapter._buildURL('model', 1);
assert.equal(url, '/foo/bars/models/1');
});
test('it can append a suffix', function (assert) {
assert.expect(1);
const Adapter = RESTAdapter.extend(AdapterBuildURLMixin, {
urlSuffix() {
return ':method'
}
});
this.owner.register('adapter:adapter', Adapter);
const adapter = this.owner.lookup('adapter:adapter');
const url = adapter._buildURL('model', 1);
assert.equal(url, '/models/1:method');
});
});