Reputation: 1424
I'm trying to get Ember Data's JSONAPIAdapter to work with nested resources. For the server part django-rest-framework-json-api is used.
My (simplified) ember models:
case.js
export default Model.extend({
firstName: attr('string'),
lastName: attr('string'),
comments: hasMany('comment'),
})
comment.js
export default Model.extend({
text: attr('string'),
case: belongsTo('case'),
})
The server's response for /api/v1/cases/4
looks like this:
{
"data": [
{
"type": "cases",
"id": "4",
"attributes": {
"first-name": "Hans",
"last-name": "Peter",
},
"relationships": {
"comments": {
"meta": {
"count": 1
},
"data": [
{
"type": "comments",
"id": "5"
}
],
"links": {
"related": "http://localhost:8000/api/v1/cases/4/comments"
}
}
}
}
]
}
Now, if i understand Ember Data and the JSON-API spec correctly, ember should request /api/v1/cases/4/comments
when i reference the comments. Instead, it requests /api/v1/comments/5
, which obviously returns a 404
.
My questions in summary:
I'm using ember v2.8.
Bonus question: I face the same problem for creating a new comment - how do i get ember to POST
to /case/4/comments
instead of /comments
?
Upvotes: 0
Views: 522
Reputation: 133
Yes this works it should be setup as follows
models/client.js
export default DS.Model.extend({
name: DS.attr('string'),
telno: DS.attr('string'),
campaigns: hasMany()
});
models/client.js
export default DS.Model.extend({
name: DS.attr('string'),
startdate: DS.attr('date'),
enddate: DS.attr('date'),
client: DS.belongsTo('client')
});
/templates/client/edit.bhs
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th></th>
<th>Name</th>
</tr>
</thead>
<tbody>
{{#each model.campaigns as |campaign|}}
<tr>
<td>{{campaign.name}}</td>
</tr>
{{/each}}
</tbody>
</table>
http://localhost:3000/api/clients/1
{
{
"links": {
"self": "http://localhost:3000/api/clients/1"
},
"data": {
"type": "clients",
"relationships": {
"campaigns": {
"links": {
"related": "http://localhost:3000/api/clients/1/campaigns"
}
}
},
"id": "1",
"attributes": {
"name": "Test",
"telno": "123"
},
"links": {
"self": "http://localhost:3000/api/clients/1"
}
}
}
http://localhost:3000/api/clients/1/campaigns
{
"links": {
"self": "http://localhost:3000/api/clients/1/campaigns"
},
"data": [
{
"type": "campaigns",
"relationships": {
"client": {
"links": {
"related": "http://localhost:3000/api/campaigns/1/client"
}
}
},
"id": "1",
"attributes": {
"enddate": "2019-01-01T00:00:00.000Z",
"name": "test",
"startdate": null
},
"links": {
"self": "http://localhost:3000/api/campaigns/1"
}
}
]
}
Upvotes: 1
Reputation: 18090
The JSON API spec does not enforce any specific URL pattern, so what you're trying to do is compliant. However, I find that working with a flat URL structure is easier with Ember Data, though there is a workaround.
You'll want to look at the ember-data-url-templates addon and add some logic from it to your model's adapter.
With that addon, here is what you can do with app/adapters/comment.js
:
import ApplicationAdapter from './application';
import UrlTemplates from 'ember-data-url-templates';
export default ApplicationAdapter.extend(UrlTemplates, {
namespace: 'api/v1', // You may or may not need this namespace setting:
// I'm a little rusty in this area :)
urlTemplate: '{+host}/case/{caseId}/comments{/id}',
urlSegments: {
contentId: function(type, id, snapshot/*, query */) {
return snapshot.belongsTo('case', { id: true });
}
}
});
Unless there is something else that the addon allows to get around this, I believe that this then locks you into that URL structure for comments across your entire app. So definitely weigh that tradeoff before deciding to go down this route.
Upvotes: 1