201-created / ember-data-hal-9000 Goto Github PK
View Code? Open in Web Editor NEWAn ember-data compatible ember-cli addon that provides a HAL adapter
Home Page: https://github.com/201-created/ember-data-hal-9000
License: MIT License
An ember-data compatible ember-cli addon that provides a HAL adapter
Home Page: https://github.com/201-created/ember-data-hal-9000
License: MIT License
We currently assume embedded records have the same name as their type.
But if we had a user model and a pet model and the user called its pet something else, like this:
// user.js
...
myGreatPet: DS.attr('pet', {async:true}
Then the incoming JSON would look like:
{
id: 'user-id',
...
_embedded: {
myGreatPet: {
id: 'pet-id',
name: 'fido'
}
}
}
And it would get restructured into:
{
user: {
}
}
Here 2 adapter hooks (keyForRelationship
and keyForLink
) are called without the adapter context. This makes it cumbersome to reuse logic that is on the consumer's adapter.
ember-data-hal-9000/addon/mixin.js
Lines 225 to 227 in e29064b
attrs is currently ignored.
One could fix this by calling the private this.normalizeUsingDeclaredMapping
json serializer method before extracting the attributes, relationships. This is how the json-api serializer does it: https://github.com/emberjs/data/blob/v2.11.0/addon/serializers/json-api.js#L409
I think it should be part of the hal serializer.
If you're interested i could open a PR to implement it.
I don't know if this is something that should be mentioned in the readme but data
is private api and shouldn't be used.
I got stung by it after using the data links directly in my templates for using a media link that is rendered in an image, i.e. {{my-image src=obj.nested.data.links.media}}
.
The problem is that the data
, which is an readonly alias for its internal model _data
is converted by ember to an ember object with __ember_meta__
, setters, getters and much more. That means the internal model is now an ember object (which is pretty bad).
This breaks pushing an already loaded record to the store (i.e. by ember after an store.find) because it tries to merge the stored record with the new incoming record. This happens without calling Ember.set
which causes the ember added setter to throw an error because it needs to be invoked with Ember.set
I solved this for myself by adding a links attribute links: attr()
to all my models and reading the links
values from that attribute. ({{my-image src=obj.nested.links.media}}
).
This could be redundant if emberjs/data#2905 is fixed (emberjs/data#3419)
Types prefaced with a curie should be handled. Presumably, since CURIEs are for documentation purposes, all that needs to happen here is to strip the curies, so property names with a colon can be split and discard the first part.
I.e., if a property name is "acme:widgets", we transform it to, simply "widgets".
Hi there !
I've started to use your adapter, which works fine for GET requests. I'm currently facing a problem when i want to create or update an object and its embeds.
The model is the following:
export default DS.Model.extend({
title: DS.attr('string'),
description: DS.attr('string'),
action: DS.belongsTo('action', {async: true}),
target: DS.belongsTo('target', {async: true})
});
According to what I understood (I hope it is not a misinterpretation), there should be 3 requests :
POST /api/entity
with content {"title": "test", "description": "test"}
PUT /api/entity/{id}/action
with content {"href": "/api/actions/{id_action}"}
PUT /api/entity/{id}/target
with content {"href": "/api/targets/{id_target}"}
Currently, only the POST request is sent. Is this normal ?
I've seen that a sample request sent is {"data":{"attributes":{"title":"test","description":"test"},"relationships":{"action":{"data":{"type":"actions","id":"8337955e-7094-4f16-bc69-d57570054318"}},"target":{"data":{"type":"targets","id":"f80cdf58-8e87-4ef7-8eb5-22338a16ccdc"}}},"type":"permissions"}}
Does that means that the links has to be treated on server-side ?
I'm using ember-data 2.2.1.
Regards,
extractAttributes
deletes keys from the payload object.
This means when calling extractId
, the developer can only read the updated object.
The call order could be changed to allow extractId to use the full incoming object.
Datas json-api serializer does it like this:
id: this.extractId(modelClass, resourceHash),
type: this._extractType(modelClass, resourceHash),
attributes: this.extractAttributes(modelClass, resourceHash),
relationships: this.extractRelationships(modelClass, resourceHash)
Since HAL is a serialization spec only, the adapter can most likely be removed.
In the wonderful world of Back-end provides data, and you're left to work with it, I have a large Ember project where most models have a related model called attribute. Being a hasMany relationship, alas results in a relational key called "attributes".
With the older version of this addon, there were almost no issues - and the ones that existed was solely from back-end data and their habit of regularly using reserved words as model / object / key names.
While Ember did require 2 differently structured calls in order to differentiate where you were getting the attributes of the model or the relational models, it still worked easily. Now with your latest release of this addon, "attributes" is now a reserved word. While agreed, not the best name to use, it isn't set as reserved by either Ember or JSON-API.
Is this likely to stay this way?
Curious to know, before I reconstruct the site replacing all instances of the term "attribute" and splice in a data.key change to and from the server, else doctor the addon.
Thanks.
This is somewhat related to #31 as it relates to output format, but I've opened a new issue as that one appears to deal mostly with wanting to serialize into HAL JSON format and the solution is to extend the HAL serializer and implement a serialize method.
What I need is to serialize into the format of DS.RESTSerializer and normalize using the HAL serializer. This was the default behavior of this addon's HAL serializer in 0.1.6 when it extended DS.ActiveModelSerializer. We're upgrading apps that were made using that version of this addon.
I could of course extend the HAL serializer and implement the serialize method to do the exact same thing as DS.RESTSerializer. But that seems very sloppy, and I hate to duplicate code.
What I'd like is to have the HAL serializer functionality as mixin. Then I can extend DS.RESTSerializer with the HAL mixin. This addon's HAL serializer can still extend DS.JSONAPISerializer and use the HAL mixin as well. Or the addon itself could provide serializers that extend Ember Data's provided serializers. (DS.JSONSerializer and DS.RESTSerializer).
Without a HAL mixin in this addon, the only solution to serialize data using the JSON or REST serializer is to not use this addon and instead copy the contents of its serializer, which I don't like almost as much as duplicating the serialize method of DS.RESTSerializer.
Would this be something you'd consider?
(Note that we intend to change to JSON API, but our server framework, Apigility, doesn't yet support JSON API. So that won't happen in the immediate future.)
I've been tinkering around with the ember data 1.13.8, the ember-data-hal-9000 and ember-data.model-fragments plugins, and I was a bit surprised to see the following data in a PATCH when I saved my model:
{
"data":{
"_id":"55b21c520fabf0ba57bf0631",
"attributes":{
"email":"[email protected]",
"user_type": "power",
"profile":{
"data":{
"attributes":{
"nickname":"SuperJoe",
"bio":null,
},
"type":"profiles"
}
},
"_updated":"Fri, 24 Jul 2015 11:06:58 GMT",
"_created":"Fri, 24 Jul 2015 11:06:58 GMT",
"_etag":"f6687527bd6a10205d7c1462109e6193b58c8ae9"
},
"type":"accounts"
}
}
I didn't expect the addition of the attributes, data, and type keys... Is there a way to turn these off and send the data back in the same format it was received? e.g:
{
"_id":"55b21c520fabf0ba57bf0631",
"email":"[email protected]",
"user_type": "power",
"profile":{
"nickname":"SuperJoe",
"bio":null,
},
"_updated":"Fri, 24 Jul 2015 11:06:58 GMT",
"_created":"Fri, 24 Jul 2015 11:06:58 GMT",
"_etag":"f6687527bd6a10205d7c1462109e6193b58c8ae9"
}
Since HAL doesn't specify an expected payload format for uploading data, the serializeIntoHash
shouldn't do what it's doing now. That should be done on a case-by-case basis by extending classes.
It will be really great to see a support of ember-cli for this :)
I'm working on building an API using Zend's Apigility product, which exposes a HAL+JSON API. One of the options you can specify for a particular resource or collection is the "max_depth", which will limit how many nested relationships are rendered in the response.
When this limit is hit, it'll still provide the name of the relationship, but the only data that exists inside that object is the _links element with the self link. Here's an excerpt from the documentation:
max_depth - integer; limit to what nesting level entities and collections are rendered; if the limit is reached, only self links will be rendered. default value is null, which means no limit: if unlimited circular references are detected, an exception will be thrown to avoid infinite loops.
https://github.com/zfcampus/zf-hal#key-metadata_map
So when this depth is reached, a resource may look something like this:
{
"id":15,
"slug":"slugify",
"title":"Slugify-12",
"_embedded":{
"articles":[
{
"id":50,
"slug":"article1",
"title":"Article 1",
"_embedded":{
"users":[
{
"_links":{
"self":{
"href":"http:\/\/localhost:8888\/users\/1"
}
}
}
]
},
"_links":{
"self":{
"href":"http:\/\/localhost:8888\/articles\/50"
}
}
}
]
},
"_links":{
"self":{
"href":"http:\/\/localhost:8888\/blogs\/15"
}
}
}
Notice that the embedded users object doesn't have any properties except for the _links proptery containing the self link.
When ember processes this response with the HAL 9000 serializer, it complains:
Error: Assertion Failed: You must include an 'id' for user in an object passed to 'push'
I can silence some of these by modifying the serializer to ignore objects without an id property, but so far it still complains on some other requests.
As far as I know, the HAL spec doesn't require a resource to have an id (but it seems that Ember Data does). Should HAL 9000 ignore resources without an id? In my case, a later request to fetch the nested object would end up returning an id, it's just not available in this particular request since it's too deep.
Any thoughts? Advice? I can continue to mess with the serializer to handle these cases better, as I feel that this is where the work should be focused (rather than in zf-hal), since the spec is so permissive.
We currently assume embedded records have the same name as their type.
But if we had a user model and a pet model and the user called its pet something else, like this:
// user.js
...
myGreatPet: DS.attr('pet', {async:true}
Then the incoming JSON would look like:
{
id: 'user-id',
...
_embedded: {
my_great_pet: {
id: 'pet-id',
name: 'fido'
}
}
}
And it would get restructured into:
{
user: {
id: 'user-id',
my_great_pet: 'pet-id'
},
my_great_pets: [{
id: 'pet-id',
name: 'fido'
}]
}
It should instead become:
{
user: {
id: 'user-id',
my_great_pet: 'pet-id'
},
pets: [{
id: 'pet-id',
name: 'fido'
}]
}
An issue to keep track of steps to take to be fully compatible with modern ember data.
The work for this is happening on ember-data-1-13-support.
_link
's properly (not sure if this requires supporting CURIEs or if that can happen later)ember-data-hal-9000 version: 0.3.3
ember-data version: 3.9.0
With ember-data version 3.8.0 the correct content-type is sent with a POST request, in particular application/hal+json, however, upgrading ember-data to 3.9.0 causes the content-type to be application/vnd.api+json.
We set the headers ourselves in the HalAdapter by doing
It looks like the ember-data guys have made a change so that the ajaxOptions method now sets the contentType to be application/vnd.api+json.
The workaround in my own code for this is to override ajaxOptions in each of my adapters to be:
/** * Overrides the AJAX options. */ ajaxOptions() { const hash = this._super(...arguments); hash.headers['content-type'] = "application/hal+json"; hash.headers['Accept'] = "application/hal+json"; return hash; },
Hi,
A recent npm audit
produced the following:
lodash <=4.17.20 Severity: critical Prototype Pollution in lodash - https://github.com/advisories/GHSA-jf85-cpcp-j695 Prototype Pollution in lodash - https://github.com/advisories/GHSA-4xc9-xhrj-v574 Prototype Pollution in lodash - https://github.com/advisories/GHSA-fvqr-27wr-82fm Command Injection in lodash - https://github.com/advisories/GHSA-35jh-r3h4-6jhm Regular Expression Denial of Service (ReDoS) in lodash - https://github.com/advisories/GHSA-29mw-wpgm-hmr9 Regular Expression Denial of Service (ReDoS) in lodash - https://github.com/advisories/GHSA-x5rq-j2xg-h7qm Prototype Pollution in lodash - https://github.com/advisories/GHSA-p6mc-m468-83gw fix available via
npm audit fix --force Will install [email protected], which is a breaking change node_modules/babel-plugin-proto-to-assign/node_modules/lodash node_modules/ember-data-hal-9000/node_modules/lodash babel-core <=6.9.1 Depends on vulnerable versions of babel-plugin-proto-to-assign Depends on vulnerable versions of lodash Depends on vulnerable versions of minimatch node_modules/ember-data-hal-9000/node_modules/babel-core broccoli-babel-transpiler <=5.7.4 Depends on vulnerable versions of babel-core node_modules/ember-data-hal-9000/node_modules/broccoli-babel-transpiler ember-cli-babel <=5.2.8 Depends on vulnerable versions of broccoli-babel-transpiler node_modules/ember-data-hal-9000/node_modules/ember-cli-babel ember-data-hal-9000 >=0.1.7 Depends on vulnerable versions of ember-cli-babel node_modules/ember-data-hal-9000 babel-plugin-proto-to-assign * Depends on vulnerable versions of lodash node_modules/babel-plugin-proto-to-assign
Looks like ember-data-hal-9000 depends on an old version of ember-cli-babel that has vulnerabilties.
Please could the maintainers have a look? I notice that this addon is still getting downloads (150+ in the last month), so likely there are a lot of people using it.
Thanks
WARNING: You've defined 'extractMeta' in (unknown mixin) which is not used for serializers extending JSONAPISerializer. Read more at http://emberjs.com/api/data/classes/DS.JSONAPISerializer.html#toc_customizing-meta on how to customize meta when using JSON API.
Defined in ember data code here and was added in 2.11.0-beta.1
Perhaps we can rename this function to avoid the warning?
The source for the serializer code has a different normalize method than I'm seeing when I use the debugger to step through the normalization of my model. It looks like 0.3.1 doesn't have the line that applies transformations but the source here does have it.
Looking at the commit history it seems like it should be there, but I'm still new to the ember and javascript worlds, so I may be misunderstanding something.
Edit: This is the commit that has the transformations applied in the normalize function. d30263c#diff-21df86ecb5f80627fb6dc6057c305faa
What License is this under?
Your custom serializer uses the old version of the Serializer API, with extract
hooks. Please upgrade your serializers to the new Serializer API using normalizeResponse
hooks instead.
more info : https://github.com/emberjs/data/blob/v1.13/packages/ember-data/lib/system/serializer.js#L28
Seems since 0.3.1
the Accept
header is set to application/vnd.api+json
. Is there's a way to edit this ? Because my API serve application/hal+json
so I got a 406
http error :/
I don't know if it's expected behavior but we have access to the relationship modelClass so why not pass it to extractId
?
https://github.com/201-created/ember-data-hal-9000/blob/master/addon/mixin.js#L205
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.