w3c / json-ld-framing

JSON-LD 1.1 Framing Specification
https://w3c.github.io/json-ld-framing/
Other
25 stars 20 forks source link

Framing on nested graphs #150

Open stevenvegt opened 1 year ago

stevenvegt commented 1 year ago

Hi wonderful people from the JSON-LD Framing group!

I have a question regarding framing on nested JSON-LD data.

Background

My question is in relation to Verifiable Credentials. I'm a maintainer of an open source credential wallet. We are now starting with the implementation of the new OIDC4VCI which supports a flow where the Issuer can ask the Holder for proof of ownership of a credential (in the form of a presentation). This can be done by the DIF Presentation exchange. In there is a Future which allows the Relying Party to query by 'frame': https://identity.foundation/presentation-exchange/#json-ld-framing-feature. This is I think so much more elegant than the json-schema filters. Since all of our credentials are in JSON-LD anyway, it seems the way to go. But I'm running into issues here.

Assumption

One can use JSON-LD framing to "query" over a set over credentials, stored as a list of graphs.

Problem

I would like to use framing to query a set of Verifiable Credentials. I made a simpler example to illustrate the problem: Input:

{
  "@context":{
    "@vocab":"http://example.org#",
    "schema":"http://schema.org/"    
  },
  "@graph":[
    {
      "@type":["Type1", "Type2"],
      "schema:name":"John"
    },
    {
      "@type":["Type2"],
      "schema:name":"John"
    },
    {
      "@type":["Type1", "Type2"],
      "schema:name":"John",
      "schema:address": {
        "@id":"uri:1",
        "schema:street":"Oneway"
      }
    },
    {
      "@type":["Type1", "Type3"],
      "schema:name":"John",
      "schema:address": {
        "@id":"uri:2",
        "schema:street":"Middleroad"
      }
    }
  ]
}

I want to query for a "credential" of Type1, name is John and address with street Oneway:

Frame:

{
  "@context":{
    "@vocab":"http://example.org#",
    "schema":"http://schema.org/"
  },
  "@type": ["Type1"],
  "schema:name": "John",
  "schema:address":{
    "schema:street":"Oneway",
    "@requireAll": true
  },
  "@requireAll": true
}

This is the output I get from the JSON-LD Playground:

{
  "@context": {
    "@vocab": "http://example.org#",
    "schema": "http://schema.org/"
  },
  "@graph": [
    {
      "@type": [
        "Type1",
        "Type2"
      ],
      "schema:address": {
        "@id": "uri:1",
        "schema:street": "Oneway"
      },
      "schema:name": "John"
    },
    {
      "@type": [
        "Type1",
        "Type3"
      ],
      "schema:address": null,
      "schema:name": "John"
    }
  ]
}

As you can see, the address of the second entry is null. I expected the result not to have this entry at all. That is also what happens when I frame on @id:

Input on @id:

{
  "@context":{
    "@vocab":"http://example.org#",
    "schema":"http://schema.org/"
  },
  "@type": ["Type1"],
  "schema:name": "John",
  "schema:address":{
    "@id":"uri:1"
  },
  "@requireAll": true
}

Output:

{
  "@context": {
    "@vocab": "http://example.org#",
    "schema": "http://schema.org/"
  },
  "@type": [
    "Type1",
    "Type2"
  ],
  "schema:address": {
    "@id": "uri:1",
    "schema:street": "Oneway"
  },
  "schema:name": "John"
}

So my questions are:

  1. Is my assumption correct?
  2. What is the difference of framing by @id and framing by value?
  3. If this is the expected behavior, is framing the logical mechanism to use in the DIF presentation exchange?
  4. Could it be that there is an example missing from the spec which gives more clarity about framing in nested structures?

Thanks for taking the time to look at this issue!

gkellogg commented 6 hours ago

This looks like it is correct; Framing explicitly will use property: null in the case that the frame specifies a property that doesn't have a value for some particular match (unless the @requireAll flag is used, in which case it won't emit this object at all).

You can get rid of the null properties by re-compacting.