Skip to content

Update one-to-many through PATCH on resource not working #492

Closed
@maurei

Description

@maurei

A core feature of the spec is currently not supported:

PATCH /articles/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "authors",
    "id": "1",
    "relationships": {
      "books": {
        "data": [
          { "type": "books", "id": "2" },
          { "type": "books", "id": "3" }
        ]
      }
    }
  }
}

Cause of the problem
Because of incomplete information on _jsonApiContext in the case of one-to-many, which is set in the JsonApiDeserializer, the DefaultEntityRepository does not attempt to update such relationships. Details:

  • In the case of one-to-one, the JsonApiDeserializer adds meta info about this to _jsonApiContext.RelationshipsToUpdate right here in the SetHasOneRelationship method.
  • This property however is not updated in the case of one-to-many: in the SetHasManyRelationship method, only _jsonApiContext.HasManyRelationshipPointers are updated, which is not enough.
  • this is where the repository would be updating one-to-many relationships if they were included in _jsonApiContext.RelationshipsToUpdate.
  • Also in the repo: AttachRelationships(oldEntity) is fired before relationship.Key.SetValue(oldEntity, relationship.Value); is called, so any updates to the relations are currently not tracked.

A complication: the request above should perform a complete replace. This means that before updating the Author.BookId to its new value, the foreign keys of all previous Books for that author should be set to null (and an error should be thrown it is non-nullable).

Solution

  • Add a hasManyAttr value to the RelationshipsToUpdate dictionary in the JsonApiDeserializer right here.
  • in the case of a complete replace, include the related entities first see this topic; same for EF Core
  • do AttachRelationships(oldEntity) before actually setting the new relationship collection.

Note: the same issue exists for many-to-many, but it requires a different fix. Will address this in a separate issue.

Environment

  • JsonApiDotNetCore Version: latest

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions