json-ld icon indicating copy to clipboard operation
json-ld copied to clipboard

Feature/Discussion: Serde integration

Open sidju opened this issue 2 years ago • 2 comments

Serde derives for json+ld would be a very helpful addition.

  • Are there plans to add Serde derives?
  • Do you have any ideas/plans about how to add context into that derive (for optional expansion/compression on serialization/deserialization)?
  • Are there any in-progress solutions or discarded attempts?

sidju avatar Nov 04 '22 11:11 sidju

I guess we could add support for ser/de a json_ld::syntax::context::Value (JSON-LD Context), is that what you mean? A complete JSON-LD document is no different from a JSON document. I'm using the json-syntax library for that part, so if you want serde support for an entire LD document, which is in fact a simple JSON document, we actually need json-syntax to support serde.

By the way there have been a lot of attempts to support many json libraries including serde-json and it has failed for multiple reasons, primarily because those libraries lack support for preserving code mapping metadata.

timothee-haudebourg avatar Nov 22 '22 10:11 timothee-haudebourg

What I would hope for is a way to inject a json-ld context into the top of a serde-json document generated from a #derive d struct (possibly with expansion but not really needed). That should be sufficient to make any json document a complete and compressed json-ld document?

I am both hunting for the efficiency and ergonomic gain from doing it in one step. (I've come to understand that json-ld often loses out performance due to first generating base json and in a separate step integrating the context.) But if you can make a more ergonomic way to convert a struct to json-ld without efficiency gains that would still be lovely.

I understand that it might not be feasible. I just feel that json-ld must support something similar to the struct derives in serde-json to be worth the effort in rust.

Some way to convert a struct directly into serde_json::Value seems to be the key, but I guess it isn't in your hands if there is no such way...

(I know that you can use a link header to inject a context separately, but the Hydra spec. is unclear on if this is supported so I'd rather have it in the same document.)

sidju avatar Nov 23 '22 20:11 sidju

There have been a lot of development since you opened the issue, and I think I can finally give some good solutions. So first, I've added support for serde for json_ld::syntax::Context so what you could do now is something like this:

#[derive(serde::Serialize, serde::Deserialize)]
struct MyCompactJsonDocument {
  #[serde(rename = "@context")]
  json_ld_context: json_ld::syntax::Context,

  name: String,

  // ...
}

You could deserialize and use the result directly without going through json_ld, but in that case your app won't be able to handle any JSON-LD document that deviate from this shape.

If you want a linked-data oriented serde-like library, you can use linked-data, which is supported by json-ld. With linked-data you can annotate your type with LD info like this:

#[derive(serde::Serialize, linked_data::Deserialize)]
#[ld(prefix("ex" = "http://example.org/"))]
struct MyCompactJsonDocument {
  #[serde(rename = "@context")]
  #[ld(ignore)]
  json_ld_context: json_ld::syntax::Context, // you might need a newtype here to have a correct default value

  #[ld("ex:name")]
  name: String,

  // ...
}

Now you still need to first deserialize to json_syntax::Value, then expand into json_ld::ExpandedDocument, but then you can use linked-data to deserialize this expanded document into MyCompactJsonDocument without too much struggle.

I can't do better than that, you have to go through an intermediate phase to handle linked data info (second case), or just ignore linked data and accept a single shape (first case).

timothee-haudebourg avatar Apr 09 '24 09:04 timothee-haudebourg

To me this looks like a good solution. I've left that API design behind me a while ago now, but this seems like it improves the ergonomy for the relevant use-cases (and performance is probably a non-issue in nearly every case). Makes me tempted to try json-ld again "soon".

Feel free to consider this issue resolved.

sidju avatar Apr 09 '24 10:04 sidju