Collection Interaction Flow with views as collection

From Hydra Community Group

Without Pagination

GET /markus

{
  "@id": "/markus",
  "givenName": "Markus",
  "familyName": "Lanthaler",
  "friends": "/markus/friends",
  ...
}


GET /markus/friends

{
  "@id": "/markus/friends",
  "@type": "Collection",
  "totalItems": 578,
  "member": [ ... ],
  "viewTemplate": {
    "@type": "ViewTemplate",
    "template": "/markus/friends{?first,last}",
    "mapping": [
      { "variable": "first", "property": "schema:givenName" },
      { "variable": "last", "property": "schema:familyName" }
    ],
    "filterSpecification": {
      "operator": "AND",
      "operands": [ 
        { "variable": "first" }, 
        { "variable": "last" }
      ]
    }
  }
}


GET /markus/friends?first=Ruben

{
  "@id": "/markus/friends?first=Ruben",
  "@type": "PartialCollectionView",
  "totalItems": 15,
  "member": [
    {
      "@id": "/ruben",
      "givenName": "Ruben",
      "familyName": "Verborgh",
    },
    ...
  ],
  "viewOf": {
    "@id": "/markus/friends",
    "@type": "Collection",
    "totalItems": 578,
    "viewTemplate": {
      "@type": "ViewTemplate",
      "template": "/markus/friends{?first,last}",
      "mapping": [
        { "variable": "first", "property": "schema:givenName" },
        { "variable": "last", "property": "schema:familyName" }
      ],
      "filterSpecification": {
        "operator": "AND",
        "operands": [ 
          { "variable": "first" }, 
          { "variable": "last" }
        ]
      }
    }
  }
}

With Pagination

GET /markus

{
  "@id": "/markus",
  "givenName": "Markus",
  "familyName": "Lanthaler",
  "friends": "/markus/friends",
  ...
}


GET /markus/friends

The server either redirects the client to /markus/friends?page=1. Without that, the client wouldn't know that it got something else than what it requested.

{
  "@id": "/markus/friends?page=1",
  "@type": "PartialCollectionView",
  "totalItems": 10,
  "member": [ ... ],
  "first": "/markus/friends?page=1",
  "next": "/markus/friends?page=2",
  "last": "/markus/friends?page=58"
  "viewOf": {
    "@id": "/markus/friends",
    "@type": "Collection",
    "totalItems": 578,
    "viewTemplate": {
      "@type": "ViewTemplate",
      "template": "/markus/friends{?first,last}",
      "mapping": [
        { "variable": "first", "property": "schema:givenName" },
        { "variable": "last", "property": "schema:familyName" }
      ],
      "filterSpecification": {
        "operator": "AND",
        "operands": [ 
          { "variable": "first" }, 
          { "variable": "last" }
        ]
      }
    }
  }
}


GET /markus/friends?first=Ruben

Again, the server either redirects the client to /markus/friends?first=Ruben&page=1. Without that, the client wouldn't know that it got something else than what it requested.

{
  "@id": "/markus/friends?first=Ruben&page=1",
  "@type": "PartialCollectionView",
  "totalItems": 10,
  "member": [
    {
      "@id": "/ruben",
      "givenName": "Ruben",
      "familyName": "Verborgh",
      ...
    },
    ...
  ],
  "first": "/markus/friends?first=Ruben&page=1",
  "next": "/markus/friends?first=Ruben&page=2",
  "last": "/markus/friends?first=Ruben&page=2"
  "viewOf": {
    "@id": "/markus/friends?first=Ruben",
    "@type": "PartialCollectionView",
    "totalItems": 15,
    "viewOf": {
      "@id": "/markus/friends",
      "@type": "Collection",
      "totalItems": 578,
      "viewTemplate": {
        "@type": "ViewTemplate",
        "template": "/markus/friends{?first,last}",
        "mapping": [
          { "variable": "first", "property": "schema:givenName" },
          { "variable": "last", "property": "schema:familyName" }
        ],
        "filterSpecification": {
          "operator": "AND",
          "operands": [ 
            { "variable": "first" }, 
            { "variable": "last" }
          ]
        }
      }
    }
  }
}


Feedback

  • Use of the view property to reference both a concrete View and a ViewTemplate is disliked
  • Some people find the use of multiple views in the response confusing
  • Some people would find it more natural to nest the views
  • There were some discussions about making the view also a collection and attach the members to it (instead of the actual collection)
  • The various concepts need clear definitions (what is the difference between a collection and a view?)
  • There are concerns that we end up defining a full-blown query language