Re: Express "go to specific page" for a collection

Hi Markus,

That's great. AFAIK, we didn't have (m)any frontend developers in the group
> till now. So your input will be very helpful to improve Hydra.


I'm happy to give input. I think my view on a Hypermedia API is quite
influenced from being a frontend developer as you will see in the following
answer.

Could you tell us why you currently favor JSON Hyper-Schema and briefly
> explain how you use it on the frontend? For example, do you use it to
> automatically generate forms?


With my "current" knowledge about HATEOAS I have the following philosophy:
HTML is the best hypermedia format I know and our JSON hypermedia format
should use the same principles.

   - That said a user who browsers the web consumes the HTML document. A
   normal user doesn't look into HTTP headers. Likewise a client should gather
   all the data it needs from the JSON payload. There is no need for the
   client to consume HTTP headers - they're only really needed for the browser
   (e.g. for caching information).
   - A user interacts with the HTML document via links (anchors or
   buttons). They know what they do, because they are labeled (e.g. "Buy now",
   "Click here to login", "Close this window"). A good JSON hypermedia format
   has a similar way to share vocabulary between server and client. Most
   formats seem to rely on "rel" and Link Types for this (e.g. "next", "prev",
   "index", "help", "edit"). I don't know if this is sufficient and I think
   this could be one of the major advantages of JSON-LD (- using schema.org
   for common vocabulary and Hydra for API-specific vocabulary). At least if I
   understand JSON-LD correctly.
   - Links in HTML documents are placed relative to their content (e.g.
   place a "share button" under every article in a blog - opposite to
   gathering "all" links at a central place). The JSON hypermedia format
   should do the same. Every resource has its own "links". (See the following
   example.)
   - A form isn't much different from a common link: it just gathers some
   additional data and than you can follow "the link of the form" via a submit
   button. You can even specify the HTTP method which should be used. A JSON
   hypermedia format should include the same information: what data is needed
   to follow the link and what HTTP method should be used?

With these requirements in mind that is how we use JSON Hyper-Schema (basic
example):

// GET https://api.example.com/users
{
  // Every "_schema" of a resource is a valid JSON Hyper-Schema.
  // Every resource has its own "_schema": Here we have a users collection
as one resource
  // containing two users which each are a resource, too. If you want these
users could also contain
  // nested resources like friends, hobbies, etc.
  "_schema": {
    // We mostly need the "links" field from JSON Hyper-Schema, but you
could really use all of JSON
    // Hyper-Schemas features (e.g. create a schema definition for the
users collection itself).
    "links": [
      {
        "rel": "self",
        "href": "https://api.example.com/users",
        "method": "GET"  // GET is default as in the browser. You don't to
specify it.
      },
      {
        "rel": "create",
        "href": "https://api.example.com/users",
        "method": "POST",
        // This schema definition tells us that we need a "name" to create
a new user and can
        // optionally pass a "description".
        // A schema definition like this refers to the request body for
POST, PUT and PATCH
        // (if you need PATCH) and to the query string for GET and DELETE.
        // (This is similar to UBER.)
        "schema": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "description": {
              "type": "string"
            }
          },
          "required": [ "name" ]
        }
      }
    ]
  },
  // Some arbitrary data on the collection resource.
  "total": 2,
  "users": [
    // Every item of "users" is also a resource, so they have "_schema"
definitions.
    {
      "_schema": {
        "links": [
          {
            "rel": "self",
            "href": "https://api.example.com/users/xxx-123"
          }
        ]
      },
      // Some arbitrary data on this user resource.
      "id": "xxx-123",
      "name": "John",
      "description": null
    },
    // Every item of "users" is also a resource, so they have "_schema"
definitions.
    {
      "_schema": {
        "links": [
          {
            "rel": "self",
            "href": "https://api.example.com/users/abc-124"
          },
          // I can dynamically add or remove "link" objects. We don't need
to use the same
          // for every user. Maybe I can remove this one, because it is an
intern and not an
          // admin.
          // We rarely need URI templates, as we include an absolute base ("
https://api.example.com/users/abc-124")
          // and define query params with "schema", if we need them.
          {
            "rel": "remove",
            "href": "https://api.example.com/users/abc-124",
            "method": "DELETE"
          }
        ]
      },
      // Some arbitrary data on this user resource.
      "id": "abc-124",
      "name": "Mica",
      "description": "Just an intern..."
    }
  ]
}


Yes, generating (or evaluating) forms is one of the benefits of this
approach which we use. E.g. in a "create new user form" we could
automatically set the "required" attribute on the input element for the
user name.

What are those benefits? Apart from the "go to specific page" feature, what
> else is currently missing in Hydra in your opinion?


I can't say what is missing in Hydra yet as I hadn't enough time to look
deeply into Hydra. A "go to specific page" feature would be very easy with
JSON Hyper-Schema: just add a new "link" object on the collection which has
a schema definition that requires a "page" param with an int value. (The
server could automatically include a "min" and "max" page, too. Very handy.)

I hope you have a picture of what we want to achieve now :)

Btw, I'm coming from Leipzig. I saw that one person in the Hydra group is
associated with the university of Leipzig. What a coincidence!
We're literally neighbors :)

Cheers,
Pipo


2014-07-08 13:17 GMT+02:00 Markus Lanthaler <markus.lanthaler@gmx.net>:

> Hi Pipo,
>
> On Tuesday, July 08, 2014 11:42 AM, Philipp Zins wrote:
> > > Does your use case really require it?
> >
> > I would say, yes. If you compare some GUI pagination patterns (see
> > https://gist.github.com/mislav/622561) you can see that roughly 50%
> > allow the user to jump to an arbitrary page.
>
> When it comes to GUIs it is indeed an often used pattern. The question
> however is, if this really needs to be supported by the API directly as
> well. It depends entirely on the application I would say. How often does a
> user jump from page 1 to page 213 and then back to page 49? If it doesn't
> happen often (and it isn't needed to support certain use cases), it's
> better to avoid supporting it directly IMO. The client can prefetch the
> next x pages and then render direct links just to those pages (1 2 3 4 ....
> last page).
>
> It all depends on the use case. I would thus like to have a concrete
> scenario that really requires it, i.e., that can't be solved otherwise. Do
> you have one?
>
>
> > What do you think about Jindřich comment with the anonymous anonymous
> > property?
>
> Jindřich said:
>
>   Instead of using hydra:freetextQuery for hydra:property mapping in
>   the hydra:IriTemplateMapping, I think you can use an anonymous
>   property with rdfs:range defined to be xsd:positiveInteger:
>
>   "property" : {
>     "rdfs:range" : "xsd:positiveInteger"
>   }
>
>   Although I'm not sure if using anonymous properties in such case is
>   an accepted practice in Hydra.
>
> I wouldn't use an anonymous property in this case as it is crucial for the
> client to understand what the property is about. Just telling the client
> that the value should be a positive integer isn't enough IMO. The client
> needs to know that this represents the page number. It also needs to know
> if the first page is 0 or 1 or if the page number is actually an offset (11
> instead of 2 for page 2 if each page has 10 items).
>
>
> > Some background: I'm mainly a frontend developer switching to the
> > backend here and there. As we try to move more development processes
> > to the client (for better iteration speeds, dynamic and fluid GUIs,
> > etc.) we need a good interface between server and client. We really
>
> That's great. AFAIK, we didn't have (m)any frontend developers in the
> group till now. So your input will be very helpful to improve Hydra.
>
>
> > like the idea of Hypermedia APIs (instead of RPC-ish "REST" APIs) and
> > I try to evaluate different solutions. We currently favor JSON Hyper-
> > Schema directly embedded in our resources,
>
> Could you tell us why you currently favor JSON Hyper-Schema and briefly
> explain how you use it on the frontend? For example, do you use it to
> automatically generate forms?
>
>
> > but I would like to explore
> > if we can move to Hydra/JSON-LD completely in the next turn as it
> > seems to be a more widely used standard and because JSON-LD is
> > supported by all major search engines. But I don't want to loose the
> > benefits of JSON Hyper-Schema.
>
> What are those benefits? Apart from the "go to specific page" feature,
> what else is currently missing in Hydra in your opinion?
>
>
> Cheers,
> Markus
>
>
> --
> Markus Lanthaler
> @markuslanthaler
>
>
>

Received on Thursday, 10 July 2014 06:43:46 UTC