ietf-wg-httpapi / rfc7807bis

Revision of RFC7807: HTTP Problem Details
Other
20 stars 8 forks source link

JSON-LD Context #10

Closed asbjornu closed 2 years ago

asbjornu commented 3 years ago

In HydraCG/Specifications#178 we have been working on making the response in the case of an API error compatible with RFC 7807. Since Hydra is based on JSON-LD, and RFC 7807 does not provide an official JSON-LD Context, we have had to define the term (property) status of RFC 7807 in the scope and namespace of Hydra.

I believe the use of RFC 7807 and JSON-LD in combination is a Venn diagram with a larger overlap than the one provided by Hydra and thus believe the community would be best served if RFC 7807bis provided its own JSON-LD Context. Hydra's JSON-LD Context for RFC 7807 looks like the following:

{
  "@context": {
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "hydra": "http://www.w3.org/ns/hydra/core#",
    "type": { "@id": "rdf:type", "@type": "@id" },
    "title": "rdfs:label",
    "detail": "rdfs:comment",
    "status": "hydra:statusCode",
    "instance": { "@id": "rdfs:seeAlso", "@type": "@id" }
  }
}
mnot commented 3 years ago

Hey @asbjornu,

I'm not familiar with Hydra, but am usually pretty skeptical about LD.

What would this require -- is this an on-the-wire change, or just an appendix to the spec?

asbjornu commented 3 years ago

An appendix would be fine. It just needs to be described somewhere and the status field needs to be mapped to a URI provided by RFC 7807bis. It would also be great if the JSON-LD Context document itself (i.e. rfc7808bis.jsonld) was made available somewhere publicly.

mnot commented 3 years ago

Ack. I think we should leave this towards the end of the process, after any other changes are incorporated.

dret commented 3 years ago

for the "the status field needs to be mapped to a URI provided by RFC 7807bis" part, @asbjornu, would urn:ietf:rfc:xxxx according to https://datatracker.ietf.org/doc/html/rfc2648 work?

asbjornu commented 3 years ago

It could, @dret. But I think it would give a better developer experience if the URI was dereferenceable, and when dereferenced, provided information about what it represented with relevant pointer(s) to RFC 7808bis. Something similar to the Atom namespace URI.

mnot commented 3 years ago

That may be tricky - is it important?

asbjornu commented 3 years ago

The dereferenceability?

mnot commented 3 years ago

Yes. We might be able to get on on ietf.org, but there's no process for doing so AIUI.

asbjornu commented 3 years ago

It's not crucial, but I do think dereferenceability provides a measurable improvement in the developer experience.

dret commented 3 years ago

just for reference, for linkset we had the same request of providing an JSON-LD context. we decided to keep the spec a JSON spec and not go out on a limb and mandate an RDF model. but we did listen to the input regarding the JSON design (we have no options for this here) and decided to create an appendix with an informational context:

https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-linkset#appendix-A

sazzer commented 3 years ago

This topic has just come up on httpapis.slack.com.

One other benefit of adding a JSON-LD context - which may or may not have already been mentioned, apologies if it has! - is that it means that all non-core properties can be defined in their own namespace and never clash with the core ones. That means adding new core properties is suddenly not a breaking change.

For example:

{
    "@context": [
        "http://www.w3.org/ns/hydra/error",
        {
            "balance": "http://example.com/problem/balance",
            "accounts": "http://example.com/problem/accounts"
        }
    ],
    "type": "https://example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "balance": 30,
    "accounts": ["/account/12345",
        "/account/67890"
    ]
}

Means that the balance and accounts keys are defined in a different namespace to the others. Accordingly, if the core spec ever added accounts as a key (for some reason) then it's different to the one in this document and thus doesn't collide.

It also means that the core names are able to be used in a non-core namespace without collision. Eg I might want a status property that is not the RFC7807 status property.

dret commented 3 years ago

On 2021-09-28 17:59, Graham Cox wrote:

One other benefit of adding a JSON-LD context - which may or may not have already been mentioned, apologies if it has! - is that it means that all non-core properties can be defined in their own namespace and never clash with the core ones. That means adding new core properties is suddenly /not/ a breaking change. It also means that the core names are able to be used in a non-core namespace without collision. Eg I might want a |status| property that is /not/ the RFC7807 status property.

that's only true for the mapped model, but it's not true for the JSON model defined by RFC 7807. this means we will have to stick with the way how it works.

asbjornu commented 3 years ago

If we rewrite @sazzer's example a bit, it should be more compatible with non-JSON-LD-capable clients by explicitly adding a namespace prefix:

{
    "@context": [
        "http://www.w3.org/ns/hydra/error",
        { "ex": "http://example.com/problem#" }
    ],
    "type": "https://example.com/probs/out-of-credit",
    "title": "You do not have enough credit.",
    "detail": "Your current balance is 30, but that costs 50.",
    "instance": "/account/12345/msgs/abc",
    "ex:balance": 30,
    "ex:accounts": [
        "/account/12345",
        "/account/67890"
    ],
    "ex:status": "Married, with children"
}
sazzer commented 3 years ago

I wonder if it's just some wording like: (but written by someone better at this than me!)

Any additional properties may conflict with properties added in future versions of the specification. This can be avoided by using globally unique property names such as URIs, or by using a JSON-LD context to ensure mapped properties are unique.

mnot commented 3 years ago

Any additional properties may conflict with properties added in future versions of the specification. This can be avoided by using globally unique property names such as URIs, or by using a JSON-LD context to ensure mapped properties are unique.

That's a pretty big change from the current approach of the spec, which is that additional properties are 'owned' by the type in question, not future versions of the spec. It would require significant changes in already deployed uses, to assure they don't conflict with future extensions.

At most, I think we could add a statement that future type-specific properties SHOULD follow some particular pattern to avoid clashes with potential future standard-added properties -- e.g., they should contain a ':', which standard properties presumably never will.

If we go down that path, we should still have a transition period (likely a few years) before we actually define any new standard properties, IMO.

mnot commented 3 years ago

Also, @asbjornu your example makes me think I don't understand the proposal yet, because it looks like an on-the-wire change is required -- the addition of a @context member. Is that the case?

dret commented 3 years ago

On 2021-10-11 02:16, Mark Nottingham wrote:

Also, @asbjornu https://github.com/asbjornu your example makes me think I don't understand the proposal yet, because it looks like an on-the-wire change is required -- the addition of a @.***| member. Is that the case?

i am curious about this one as well. it used to be the case that JSON-LD did not support "implicit" contexts, i.e. you always needed to explicitly reference the context within the JSON structure.

i think i can vaguely remember that there were ideas or plans to change that, but i don't know what happened since then.

tpluscode commented 3 years ago

JSON-LD has had this from early days that a context can be referenced using LINK header

A published using the ex: extension would have to link to their own context resource

asbjornu commented 3 years ago

Yes, as @tpluscode writes, @context can be removed from the body and smashed into a Link header instead. As long as the linked JSON-LD context provides a mapping for the compact IRI prefixes used in the JSON body (in the example being ex:), it should be processable as JSON-LD (and by extension, RDF).

dret commented 3 years ago

On 2021-10-11 02:08, Mark Nottingham wrote:

At most, I think we could add a statement that future type-specific properties SHOULD follow some particular pattern to avoid clashes with potential future standard-added properties -- e.g., they should contain a ':', which standard properties presumably never will.

oh look, "x-" is back in business again! ;-)

ioggstream commented 2 years ago

While a jsonld context can be useful, I think that the payload should not be impacted (eg avoid stuff like ex:balance ...). For example @vocab could be used to reference an URL where retrieving all the definitions, including the problem ones.

mnot commented 2 years ago

@asbjornu what exactly do you want to see in the spec -- could you do a PR by any chance?

asbjornu commented 2 years ago

@mnot, what I would like to see in the spec depends on whether we are able to host the problem.jsonld document containing the JSON-LD Context somewhere dereferenceable. Are we? If we are, what would its full URI be?

dret commented 2 years ago

On 2022-03-27 22:12, Asbjørn Ulsberg wrote:

@mnot https://github.com/mnot, what I would like to see in the spec depends on whether we are able to host the |problem.jsonld| document containing the JSON-LD Context somewhere dereferenceable. Are we? If we are, what would its full URI be?

that sounds like another "HTML DTD" drama in the making. is there any precedent where IETF hosts files that will be accessed at runtime by all applications using the spec?

tpluscode commented 2 years ago

I think I agree with @dret's sentiment here. Would probably show how such a document should look like and suggest that API publishers could reuse an existing context, or publish it themselves, if they so choose. The latter would be required if defining any additional mappings would be required

For example, hydra now has one dereferencable from http://www.w3.org/ns/hydra/error

sazzer commented 2 years ago

I'm not a hydra expert by any means, but if different APIs host their own copy of the .jsonld file then it will have a different absolute URL. Does that mean that identical documents served from different APIs will parse differently because of those different URLs?

Cheers -- Graham Cox

On Sun, 27 Mar 2022, 21:35 Tomasz Pluskiewicz, @.***> wrote:

I think I agree with @dret https://github.com/dret's sentiment here. Would probably show how such a document should look like and suggest that API publishers could reuse an existing context, or publish it themselves, if they so choose. The latter would be required if defining any additional mappings would be required

For example, hydra now has one dereferencable from http://www.w3.org/ns/hydra/error

— Reply to this email directly, view it on GitHub https://github.com/ietf-wg-httpapi/rfc7807bis/issues/10#issuecomment-1080014154, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAQEGC6SQ3CCW64ZUBIXLDVCDIDVANCNFSM4W4RALRA . You are receiving this because you were mentioned.Message ID: @.***>

tpluscode commented 2 years ago

It would be true if the JSON-LD would have a @base. Clearly not what one should do in the case of a shared context.

Otherwise no, the sole fact that a context is delivered from a remote location does not have bearing on resolving relative URIs

asbjornu commented 2 years ago

There's two different URIs being discussed here.

Vocabulary URI

The Vocabulary URI is the base URI for the shared vocabulary containing the terms defined in rfc7807bis, sort of like an XML namespace URI. There's a clear benefit from all RDF consumers of problem+json to use the same base URI for the terms defined within the JSON-LD context, binding them all to the same, shared vocabulary. The most common such shared vocabulary base URI is http://schema.org/.

The Vocabulary URI can be dereferenceable, but doesn't have to be. If this URI is made dereferenceable, it should serve human-readable documentation such as that of the Atom namespace URI. The dereferenceability of namespace URIs are not problematic or comparable to the HTML DTD debacle, afaik. They just provide better developer experience than a non-dereferenceable URI.

If we are able to mint this URI like we were able to mint the Atom namespace URI, it could be something like https://www.w3.org/ns/Problem#. This in turn gives the status term the absolute URI https://www.w3.org/ns/Problem#status, which is what makes it sharable across different RDF implementations.

Context URI

The Context URI is the URI pointing to a JSON-LD Context document containing the definition for each of the terms defined in rfc7808bis. If made available, this URI must be dereferenceable, but should bear no meaning on the processing of the problem+json document as the terms should be resolved to the Vocabulary URI. If a Context URI is made available (and dereferenceable), it should respond with something like this:

200 OK
Content-Type: application/ld+json
Content-Length: 373

{
  "@context": {
    "@vocab": "https://www.w3.org/ns/Problem#",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "type": { "@id": "rdf:type", "@type": "@id" },
    "title": "rdfs:label",
    "detail": "rdfs:comment",
    "status": "status",
    "instance": { "@id": "rdfs:seeAlso", "@type": "@id" }
  }
}

If we are able to host this document, it could be something like https://www.w3.org/ns/Problem/context.jsonld. This URI can indeed lead to the same issues as the HTML DTD described by @dret, although I doubt this URI gaining the same popularity and widespread usage as that of the HTML DTD. This URI can then be used with problem+json responses as such:

200 OK
Content-Type: application/problem+json
Content-Length: 273
Link: <https://www.w3.org/ns/Problem/context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"

{
  "type": "https://example.com/probs/out-of-credit",
  "title": "You do not have enough credit.",
  "detail": "Your current balance is 30, but that costs 50.",
  "instance": "/account/12345/msgs/abc",
  "balance": 30,
  "accounts": ["/account/12345", "/account/67890"]
}

For example, hydra now has one dereferencable from http://www.w3.org/ns/hydra/error

@tpluscode, do you mean that this will become dereferenceable once Hydra reaches W3-REC status? Because it doesn't resolve to anything useful currently.

tpluscode commented 2 years ago

@asbjornu no, it should totally work and it did not long ago indeed. Will fix asap

tpluscode commented 2 years ago

Here's the source which should be served: https://github.com/HydraCG/Specifications/blob/master/spec/latest/core/error.jsonld

asbjornu commented 2 years ago

If we are already able to serve the JSON-LD Context document from W3C under the Hydra namespace, minting a non-Hydra namespace to serve the same document should be no problem, should it?

tpluscode commented 2 years ago

Ok, it's live again. And should stay that way :)

mnot commented 2 years ago

I don't think we're going to be able to publish an RFC with a URL pointing to GitHub; while that's OK for things like a registry entry, the RFC Editor will balk at doing this.

Popping up a level -- what's the reason this needs to be in the RFC?

asbjornu commented 2 years ago

I don't think we're going to be able to publish an RFC with a URL pointing to GitHub; while that's OK for things like a registry entry, the RFC Editor will balk at doing this.

Yeah, that makes sense.

Popping up a level -- what's the reason this needs to be in the RFC?

Which "this" are you referring to? 😄 The vocabulary or the context?

If we are able to pull some strings in W3C to have them host a vocabulary URI such as https://www.w3.org/ns/Problem, it would be great to have that in the RFC so we have a shared and canonical vocabulary URI that every JSON-LD consumer of rfc7807bis can refer to.

When it comes to the context URI, I'm not sure what we should do, but we may perhaps just provide a sample context in a non-normative section of the RFC and leave it up to consumers to host it themselves. The most important bit is to not cause fragmentation of the vocabulary URI by having every consumer mint their own.

tpluscode commented 2 years ago

You talk of the error context document?

FWIW it is http://www.w3.org/ns/hydra/error and not GitHub. It's not even a redirect but a rewrite.

I mentioned it because the real one was down

mnot commented 2 years ago

Trying again. What is the actual text that you'd like to see in the RFC?

Is it enough to add a short, non-normative appendix that looks like this?

JSON-LD

The JSON LD [ref] context for Problem Details can be found at http://www.w3.org/ns/hydra/error.

mnot commented 2 years ago

This issue is now the last open issue on this specification -- if there aren't any concrete proposals for text, I'm inclined to close it with no action.

tpluscode commented 2 years ago

:pensive:

asbjornu commented 2 years ago

Sorry for being awol, but I’m on parental leave with a daughter that barely sleeps so I don’t have much time on my hands until August. I would be happy to review a PR trying to solve this or I will try to find time during the next days to write something myself. Can you please reopen, @mnot?

mnot commented 2 years ago

The document is in Working Group Last Call, which is a two-week window. Write up a PR?

asbjornu commented 2 years ago

I hope to be able to dedicate some time to write a PR for this next week.

asbjornu commented 2 years ago

I'm sorry time hasn't allowed me to spend any time on this or any other spare time projects lately. I suppose it's now too late to do anything about this, @mnot?

mnot commented 2 years ago

"Too late" might be a bit too strong, but it's going to be increasingly hard to make a change as the document progresses. I you want to make a proposal you should probably clear it with the chairs first.