Pushing to a relationship that affects resource


#1

Hi,

Resource of type “rooms” has attribute “people_in” and relationship “people”. POST operation to /rooms/1/relationships/people (self link of the relationship) adds a person to the room. How should correct response look?

I want to include the rooms/1 resource into response as it was changed during the request. Can I omit the relationship itself as in “no content” response?


#2

Can you explain to me the difference between “people_in” and “people”? Those sound like they should be the same thing to me, which would simplify this case a lot.


#3

Sorry that I was not clear about “people_in” - it is a counter of people that are in the room. Represents the current size of the “people” relationship. You can argue that it shouldn’t be “materialized” as an attribute, but it is materialized in the API and actually in the DB. My model has also people_max attribute.

It’s very common case if you think it’s not I can demostrate you more examples where it’s handy and sometimes even required to materialize counters.


#4

Ahh, ok, that makes sense.

Usually, the response would just be a 204. But, since you want to provide extra data about the result…

Yes, you can omit the relationship data itself, as in the 204 case, and you should put your extra data (either the full rooms/1 resource or just the updated count) in meta. This information must go in "meta", rather than say "data" or "included", since those other keys always refer to the relationship’s contents, not the content of the resource that owns the relationship.

So the response could simply look like this:

200 OK
Content-Type: application/vnd.api+json

{
  "meta": {
     "people_in": 5 // new count here
  }
}

#5

Hm. I missread your reply. Why meta? Is it because of “full linkage requirement” of compound documents or because of some other reason I don’t see?


#6

It’s simply because the response is coming from a relationship URI and, at a relationship URI, "data" always contains the resource identifier objects of the relationship’s targets, and "included" always represents the full resources for those targets. But you want to include information not about the targets of the relationship (i.e. the people) but about the owner of the relationship (i.e. the room). And because there’s no standard place for that, it has to go in "meta".


#7

Understood :cry:

Consider adjusting spec that server MAY send included with whatever content it wants in any response :slight_smile:

It would be so handy to send out objects to client that were “side affected” by the operation. As you understand elements in the relationship even have no pointer to this particular room, so you can not request to include the room from the client side.

Going to put included into meta for now and customize client’s code to understand such includes in any response to update client’s resources cache.


#8

Sounds good @ruz!

Eventually, I think your use case will be addressed by #795, which could allow you to get the updated room in the same response.


#9

I don’t see how “multiple transactional updates in one request” related to this. What I suggest and expected to be allowed is for server to add any objects to “includes”. Client posts a comment to an article #123, this is one operation and well defined in the spec, but as side effect of this action server also updates comments_counter attribute on the article #123. What I want is to free client from repeating this operation on the article object and I want to do this by including up to date article representation into response of “post a comment” operation.

Spec already have an exception to “full linkage” rule - sparse fields. Maybe this requirement is not that good afterall.


#10

The connection to #795 is that one operation from #795 would be a “fetch” so you could update the relationship and then get the new version of the owning resource (the room) in a single request/response.

To me, this feels like it would make the meaning of "included" a bit too confusing/open-ended, but it’s an interesting idea. Can you open an issue about it on Github? I’m curious what others think…


#11

Why isn’t it permitted for the response to look like this?:

Or is it that such a response is allowed but just is not suitable for @ruz because the updated relationship is present (rather than omitted) and because the person has a relationship to the room (which @ruz seems not to want for some reason)?


#12

Read closely “full linkage requirement”. Response 200 would’ve worked for me just fine, but neither 200 nor 204 allow you to send an include not referenced in data or another include because of the requirement.


#13

Can you show exactly which section of the spec you think prevents this?
I based my suggestion on this which states:

I think my suggestion complies - the included person is referenced by a resource identifier in the primary data, and the included room is referenced by a resource identifier in a resource linkage (data object in a relationship object) in an included resource (the included person).