Comments (8)
In my reading of the specification, an attribute value should be replaced. It does not make a difference if the attribute value is a primitive or a complex data structure. If an attribute's value is not replaced but patched, the server "changes the targeted resource in ways other than those specified by the request" and therefore must not response with 204 No Content
.
Using complex data structures as attribute values is a foot gun in my experience. I would recommend avoiding it. There are two alternatives:
- Flatten the complex data structure:
{ "data": { "attributes": { "addressStreet": "43 Wallaby Way", "addressCity": "Sydney" } } }
- Model the complex data structure as a separate resource with a relationship.
Partially updating a resource's attribute is not the only issue you will run into when using complex data structures as attribute values. Sparse fieldsets and sorting is also not working well for that case.
from json-api.
Following up. Internally, our team decided to go with a "maximum REST" approach for now, and model the nested JSON attribute we were considering as a separate resource instead. We may experiment with the atomic operations extension when customers have a use case for bulk updates to multiple sub resources. This will present the least surprising, even if not as convenient, API.
from json-api.
I would have appreciated more guidance on this as well.
from json-api.
In my reading of the specification, an attribute value should be replaced.
What specifically suggests this reading to you? I'm genuinely hoping I've missed something, because I would like to be able to know in detail what the spec says, and either make a decision to follow it or deliberately not follow it, and document that. But at the moment it seems underspecified to me.
"changes the targeted resource in ways other than those specified by the request"
This language sounded to me like, for example, if a PATCH request incremented the resource's revision number or something like that. It just seems unclear to me right now what a PATCH request actually specifies.
Using complex data structures as attribute values is a foot gun in my experience. I would recommend avoiding it. Partially updating a resource's attribute is not the only issue you will run into when using complex data structures as attribute values. Sparse fieldsets and sorting is also not working well for that case.
This is fair, but how would I sort a list of house
s e.g. by city name if their address
es were relationships instead of structured attributes? We'd have to solve this problem one way or another.
from json-api.
This is fair, but how would I sort a list of
house
s e.g. by city name if theiraddress
es were relationships instead of structured attributes? We'd have to solve this problem one way or another.
There's not that much limitation on filter names and their effects. You can have an endpoint supporting Sorry, misread sorting for filtering. Either way, as @jelhan mentions below, sorting is supported as well.GET /houses?filter[address.city]=asc
.
I agree with @jelhan that attributes should be replaced completely independent of the structure of their value. It sounds logical and prevents all kinds of issues. So if the spec doesn't make this clear, I would assume that to be a missed point, but not for it to be opened up.
Another kind of issue you'll run in to, for example with addresses, is optional sub values. Does a missing sub value mean it should be skipped or removed. When sub values can be skipped you can never remove them.
Consider this value for an address attribute:
{
"street": "Foo",
"number": "42",
"suffix": "B",
}
When PATCHing it with:
{
"number": "43",
}
Here you could think street and suffix should be skipped because not mentioned. But then you can never get rid of the suffix:
{
"street": "Bar",
"number": "2315",
}
I'd say this leads to that the spec has to mean that an attribute is replaced completely regardless of its structure.
from json-api.
This is fair, but how would I sort a list of
house
s e.g. by city name if theiraddress
es were relationships instead of structured attributes? We'd have to solve this problem one way or another.There's not that much limitation on filter names and their effects. You can have an endpoint supporting
GET /houses?filter[address.city]=asc
.
Sorting by relationship's attribute is even covered by the base specification itself. A sort field may be a dot-seperated relationship path. A request to filter the houses by city
attribute of a to-one address
relationship may look like this: GET /houses?sort=address.city
from json-api.
What specifically suggests this reading to you?
My understanding is primarily based on the definition of an attribute's value. The entire complex data structure is the value of the attribute. A client requests with a PATCH
to update the values of specified attributes and relationships to the given value. This is made very clear for updating relationships with a PATCH
request to the resource. It is implicitly also assumed for updating attributes. But I agree that this could be more clarified.
Additionally to the issues listed already by @lode, merging complex data structures instead of replacing them on an update also doesn't work well if you take more than a simple object into account. How do you handle arrays?
@dgeb: Please speak up if the intent was a different one. I was not part of the discussions when those fundamentals were defined.
from json-api.
Does a missing sub value mean it should be skipped or removed.
How do you handle arrays?
As far as I can tell, JSON:API is agnostic to these questions. That's why I mentioned the idea of an implementation deciding to use, for example, JSON Merge Patch rules which answer both those questions.
But without the spec saying anything on the subject, it seems to me like an implementation could choose to apply JSON Funky Patch rules, which might behave differently. And that might be unexpected for clients, or it may just mean the API needs to be carefully documented.
There are pros and cons of Merge Patch versus attribute replacement, but I just wanted to know whether the spec is intended to have an opinion.
My understanding is primarily based on the definition of an attribute's value. The entire complex data structure is the value of the attribute.
I agree this is probably the most sensible and least surprising reading of the spec. I just wanted to check, as I can't find any actual language in the spec to this effect.
from json-api.
Related Issues (20)
- consider support for implementation-specific members HOT 2
- JSON-LD integration example HOT 1
- Clarify intent of links member HOT 1
- How does one document a JSON:API HOT 4
- 1.1 spec disallows e.g. filter[author.name] HOT 4
- Inclusion of related resources for heterogeneous collections
- PrimaryResourceType not to be null at this point HOT 1
- Create/update relationships having attributes? HOT 3
- ember-data link on implementations page is broken HOT 2
- Bulk delete as either extention or implementation HOT 4
- Extend Spec To Allow Creation of Multiple Resources in One API Call HOT 1
- Profiles should be allowed to define query parameters HOT 5
- JSONRenderer does not extract includes from PolymorphicModelSerializer properly HOT 1
- Version 1.1 is incomplete about where extension members are allowed.
- Suggestion: Add GitHub topics to help with discoverability
- Explain intent of local identifiers in a note in the spec
- https://jsonapi.org/schema#/definitions/failure 404 error HOT 3
- v1.1 docs mix location of "links" for GET vs POST HOT 1
- Bug: Update twitter icon from Bird to X
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from json-api.