Skip to content

Commit

Permalink
handle absolute / relative paths and full URLs in links
Browse files Browse the repository at this point in the history
fixes emberjs#1365

absolute paths start with a leading / and will
use only the provided host provided to the adapter

cf. { posts: [{ id: 1, links: { comments: "/posts/1/comments" }}] }

relative paths construct an URL from the record the
relationship is embedded in:

cf. { posts: [{ id: 1, links: { comments: "comments" }}] }

full URLs links will pass through the link transparently:

cf. { posts: [{ id: 1, links: { comments: "http://example.com/posts/1/comments" }}] }

note that all of the above examples are equivalent
to each other.
  • Loading branch information
tim-evans committed Sep 26, 2013
1 parent 39e999a commit 6aee271
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 5 deletions.
29 changes: 24 additions & 5 deletions packages/ember-data/lib/adapters/rest_adapter.js
Expand Up @@ -247,7 +247,10 @@ DS.RESTAdapter = DS.Adapter.extend({
@returns Promise
*/
findHasMany: function(store, record, url) {
return this.ajax(this.urlPrefix(url), 'GET');
var id = get(record, 'id'),
type = record.constructor.typeKey;

return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
},

/**
Expand Down Expand Up @@ -280,7 +283,10 @@ DS.RESTAdapter = DS.Adapter.extend({
@returns Promise
*/
findBelongsTo: function(store, record, url) {
return this.ajax(this.urlPrefix(url), 'GET');
var id = get(record, 'id'),
type = record.constructor.typeKey;

return this.ajax(this.urlPrefix(url, this.buildURL(type, id)), 'GET');
},

/**
Expand Down Expand Up @@ -388,13 +394,26 @@ DS.RESTAdapter = DS.Adapter.extend({
return url;
},

urlPrefix: function(path) {
urlPrefix: function(path, parentURL) {
var host = get(this, 'host'),
namespace = get(this, 'namespace'),
url = [];

if (host) { url.push(host); }
if (namespace) { url.push(namespace); }
if (path) {
// Absolute path
if (path.charAt(0) === '/') {
if (host) {
path = path.slice(1);
url.push(host);
}
// Relative path
} else if (!/^http(s)?:\/\//.test(path)) {
url.push(parentURL);
}
} else {
if (host) { url.push(host); }
if (namespace) { url.push(namespace); }
}

if (path) {
url.push(path);
Expand Down
54 changes: 54 additions & 0 deletions packages/ember-data/tests/integration/adapter/rest_adapter_test.js
Expand Up @@ -734,6 +734,60 @@ test('buildURL - with host and namespace', function() {
}));
});

test('buildURL - with relative paths in links', function() {
adapter.setProperties({
host: 'http://example.com',
namespace: 'api/v1'
});
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });

ajaxResponse({ posts: [{ id: 1, links: { comments: 'comments' } }] });

store.find('post', 1).then(async(function(post) {
ajaxResponse({ comments: [{ id: 1 }] });
return post.get('comments');
})).then(async(function (comments) {
equal(passedUrl, "http://example.com/api/v1/posts/1/comments");
}));
});

test('buildURL - with absolute paths in links', function() {
adapter.setProperties({
host: 'http://example.com',
namespace: 'api/v1'
});
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });

ajaxResponse({ posts: [{ id: 1, links: { comments: '/api/v1/posts/1/comments' } }] });

store.find('post', 1).then(async(function(post) {
ajaxResponse({ comments: [{ id: 1 }] });
return post.get('comments');
})).then(async(function (comments) {
equal(passedUrl, "http://example.com/api/v1/posts/1/comments");
}));
});

test('buildURL - with full URLs in links', function() {
adapter.setProperties({
host: 'http://example.com',
namespace: 'api/v1'
});
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });

ajaxResponse({ posts: [{ id: 1, links: { comments: 'http://example.com/api/v1/posts/1/comments' } }] });

store.find('post', 1).then(async(function(post) {
ajaxResponse({ comments: [{ id: 1 }] });
return post.get('comments');
})).then(async(function (comments) {
equal(passedUrl, "http://example.com/api/v1/posts/1/comments");
}));
});

test('buildURL - with camelized names', function() {
adapter.setProperties({
pathForType: function(type) {
Expand Down

0 comments on commit 6aee271

Please sign in to comment.