GithubHelp home page GithubHelp logo

Comments (8)

jelhan avatar jelhan commented on June 12, 2024 1

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:

  1. Flatten the complex data structure:
    {
      "data": {
        "attributes": {
          "addressStreet": "43 Wallaby Way",
          "addressCity": "Sydney"
        }
      }
    }
  2. 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.

crabmusket avatar crabmusket commented on June 12, 2024 1

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.

freddrake avatar freddrake commented on June 12, 2024

I would have appreciated more guidance on this as well.

from json-api.

crabmusket avatar crabmusket commented on June 12, 2024

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 houses e.g. by city name if their addresses were relationships instead of structured attributes? We'd have to solve this problem one way or another.

from json-api.

lode avatar lode commented on June 12, 2024

This is fair, but how would I sort a list of houses e.g. by city name if their addresses 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. Sorry, misread sorting for filtering. Either way, as @jelhan mentions below, sorting is supported as well.


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.

jelhan avatar jelhan commented on June 12, 2024

This is fair, but how would I sort a list of houses e.g. by city name if their addresses 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.

jelhan avatar jelhan commented on June 12, 2024

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.

crabmusket avatar crabmusket commented on June 12, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.