hofff / json-ld

JSON-LD tooling for Symfony
1 stars 0 forks source link

Denormalization behavior with embedded models #1

Open backbone87 opened 6 years ago

backbone87 commented 6 years ago

Lets assume we have entity Book and Chapter. We will treat this as a 1-1 relation, but this also applies to 1-n relations. ` (i will use yaml serialization for comments)

We asume that we have 1 book and 2 chapters already and that one chapter is related to book (1-1 remember).

"@id": /books/great-book
"@type": type:Book
title: A Great Book
content: /chapters/first-chapter
"@id": /chapters/first-chapter
"@type": type:Chapter
headline: The Beginning
"@id": /chapters/second-chapter
"@type": type:Chapter
headline: Continue

The context

type: http://example.com/
title: http://example.com/title
content:
  "@id": http://example.com/content
  "@type": @id
headline: http://example.com/headline

There are actually several different possibilities when updating the Book with an embedded update. We do a PUT /books/great-book with the following documents

"@id": /books/great-book # can be infered by endpoint
"@type": Book # can be infered by endpoint
content:
  "@id": /chapters/first-chapter
  headline: Lets Start

Meaning:

"@id": /books/great-book # can be infered by endpoint
"@type": Book # can be infered by endpoint
title: A Great Book
content:
  "@id": /chapters/second-chapter
  headline: Going On

Meaning:

"@id": /books/great-book # can be infered by endpoint
"@type": Book # can be infered by endpoint
title: A Great Book
content:
  "@id": /chapters/new-chapter
  headline: Finish

Meaning:

"@id": /books/great-book # can be infered by endpoint
"@type": Book # can be infered by endpoint
content:
  headline: Lets start

Meaning:

While the first 2 examples are pretty straight forward, the last two can get wonky.

@soyuka Whats your opinion on this?

soyuka commented 6 years ago

For the first examples, it looks a lot like the behavior of what a PATCH method should do no?

I agree with most of the examples, and I think they'd almost work as-is in ApiPlatform. However:

"@id": /books/great-book # can be infered by endpoint
"@type": Book # can be infered by endpoint
title: A Great Book
content:
  "@id": /chapters/new-chapter
  headline: Finish

Assumes that the id of new-chapter is writable. If not it'll result in an error ofc. The second example with a blank node should be an auto generated identifier IMO or results in an error.

Tldr if you add the information of how the identifier is built (writable/readonly) you can resolve the last two cases.

backbone87 commented 6 years ago

For the first examples, it looks a lot like the behavior of what a PATCH method should do no?

api platform doesnt make a distinction between PATCH and PUT. there is also no real consensus about how a PUT vs PATCH should look like. The only real hard distinction from a protocol view is that PUT must be idempotent while PATCH may not.

Regarding the last 2 examples: you must take into account that we are not necessarily translating to a relational persistance layer, but an in memory object model.

For example an EmailAddress value object with 2 properties email (required) and displayName (optional) has no artificial identity (its value identifies it). You can use embeddables in doctrine to model this and in JSON-LD it may be a blank node object. Idk if its fine to give it any identity you want besides a blank node id, because after deserialization the @id of such an object would not matter anymore.

soyuka commented 6 years ago

Regarding the last 2 examples: you must take into account that we are not necessarily translating to a relational persistance layer, but an in memory object model.

Totally agreed. We still have some issues with blank nodes IIRC https://github.com/api-platform/core/pull/956

May I ask though how you're using this repository? May it be useful to others? (maybe just update the README if it is :smile: )

backbone87 commented 6 years ago

in some api-platform tickets there was the wish to rewrite/redesign the serializers. based on that i started this repo to implement a well designed json-ld serializer. while it is now directly implemented as a symfony serializer (normalizer+encoder), i maybe want to allow standalone serialize feature and just provide an integration with symfony serializer.