The relation to the target SHOULD be interpreted as specifically from the instance object that the schema (or sub-schema) applies to
"The URI, whether the link is shown or not, etc is decided at run-time"How are they decided? If they are being decided using magic code in the client, then what's the point in even including the rel and method? The link definitions in the schemas are not useful.
However, the RESTful way to approach this situation is to include the link URIs in the item. Say you have this schema:{"id": "http://andrei/myschema","type": "object","links": [{"href": "{id}", "rel": "self"},{"href": "{author}", "rel": "author"},{"href": "{reply}", "rel": "action-reply", "method": "POST", "schema": {...}}]}This instance:{"id": "http://andrei/items/12345","test": true}would have the "self" link defined, but would not have enough information to automatically assemble the others.This instance:{"id": "http://andrei/items/12346","author": "/authors/andrei"}would have the "self" link and the "author" link.
I posted a similar post about that very same thing.The more I think about it, the more I believe coupling the data-representation with some external "out-of-band" information (e.g. an json-schema resource to be downloaded elsewhere by the client) sounds breaking the hypermedia and data self-descriptiveness constraint of REST.In my own interpretation, uniform contract of REST APIs are defined by 1) uniform-agreed mime-types, 2) uniform-agreed relation-types and 3) uniform-agreed transport (HTTP methods/headers).
- The specified mime-type (e.g. application/json) passed on Accept/Content-Type HTTP headers is sufficient to process the data representation of the returned structure (which is described elsewhere, e.g. in a XSD or JSON schema). E.g. If the browser or user agent "knows" the "image/jpg" Content-Type, it will be able to render it without external information. The mime types can be vendor-specific but restricts their interoperability with other user-agents which may ignore them.
- The specified relation-type (e.g. "parent" or "next" or "prev") passed using Link HTTP headers or retrieved from HTTP body is sufficient to interpret how to interact with the related resource (which might be described elsewhere, eg. IANA registry or json schema). E.g. If the browser or user agent "knows" the "next" or "prev" relation link type, it will be able to navigate between the previous or next resource within the context of the current resource. The relation types can be vendor-specific too, but here again, it restricts their interoperability with other user-agents who will ignore them.
Relying on information out-of-band of current resource HTTP context to interpret the data received sounds not REST to me. Whether the external information is a JSON schema or even a plain WIKI documentation page, it breaks the self-descriptiveness of the resource. Unless you embed the schema within the json instance representation, I don't think we should call this RESTful.My 0.02$
A parser can be very generic (e.g. a browser can parse json or html data very generically), yet you could have a schema that describes in much details additional information about the format of json/html/xml your provider sends.The idea is to have a generic way to parse links from any document, and with that very generic parser, have the ability to convey navigation from the data being returned (without knowing necessarily the format of the data returned). Consider e.g. the HTTP Link Headers received on a HTTP GET that returns HTML. Say you receive 2 links with "prev" and "next". You don't need the details of the data being returned (that could be described in your json schema, or could be plain binary data, eg. a XLS spreadsheet or an JPG image) to propose generically a "back" and "next" button to navigate the data (following the links). This is based on your uniform contract that HTTP and the fact link relations "next" and "prev" are IANA standardized. I don't necessarily needs the knowledge of the MIME type (application/jpg or whatever) to enable hyperlinking.Schemas describe the payload, and may describe hypermedia links in more details. Very useful as a mean of validation and/or documentation. But not as a mean of parsing the data. If this is required for parsing the data, then it should be part of the document itself.With the example I provided above, you woul not need any schema knowledge and yet your user-agent/browser/parser would be able to follow links, assuming it can handle HTTP Links.
I also disagree that it is interpreter's job to "attach URIs to link relations". Any data point to back that affirmation? Availability of links and actual URLs to navigate these links should be server logic, based on application internal state, and should not be parser/client job to construct.
I find schemas (XSD or json-schema) a GREAT way to describe your API contract. JSON-schema also allows to document your actions and links (including those non standard ones). I agree the client will build logic against that API contract (and as such, will build its code based on a given version of the API contract / based on a given schema version.The only thing I struggle with, is expecting the client to download the current version of the schema, at all call, to "detect" changes the server may have decided to undertake, so it can dynamically construct URIs of the links/actions that fits the server implementation. I actually would go further in saying the URI template should not even be part of the schema, it is an implementation details that should be defined outside of the API contract (therefore outside of the schema defining the API contract).
--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To unsubscribe from this group and stop receiving emails from it, send an email to json-schema...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
On 15 February 2013 13:15, Philippe Marsteau <mars...@gmail.com> wrote:A parser can be very generic (e.g. a browser can parse json or html data very generically), yet you could have a schema that describes in much details additional information about the format of json/html/xml your provider sends.The idea is to have a generic way to parse links from any document, and with that very generic parser, have the ability to convey navigation from the data being returned (without knowing necessarily the format of the data returned). Consider e.g. the HTTP Link Headers received on a HTTP GET that returns HTML. Say you receive 2 links with "prev" and "next". You don't need the details of the data being returned (that could be described in your json schema, or could be plain binary data, eg. a XLS spreadsheet or an JPG image) to propose generically a "back" and "next" button to navigate the data (following the links). This is based on your uniform contract that HTTP and the fact link relations "next" and "prev" are IANA standardized. I don't necessarily needs the knowledge of the MIME type (application/jpg or whatever) to enable hyperlinking.Schemas describe the payload, and may describe hypermedia links in more details. Very useful as a mean of validation and/or documentation. But not as a mean of parsing the data. If this is required for parsing the data, then it should be part of the document itself.With the example I provided above, you woul not need any schema knowledge and yet your user-agent/browser/parser would be able to follow links, assuming it can handle HTTP Links.
Sure - using the HTTP Link header, you can communicate links completely independently of the payload type.
I also disagree that it is interpreter's job to "attach URIs to link relations". Any data point to back that affirmation? Availability of links and actual URLs to navigate these links should be server logic, based on application internal state, and should not be parser/client job to construct.
Sorry, I didn't mean construct - I meant identify.
When I view an HTML page, the server has helpfully put all the links in for me, but my client (the browser) uses its innate knowledge of HTML to identify them as links and display them to me as such.
That kind of innate knowledge is required for any client to use links, in any data format (unless, as you point out, all links are communicated in the HTTP headers - but that's not very common). The problem currently is that there are a billion different custom JSON formats out there - so you cannot write a "client that understands JSON and identifies hyperlinks", because the hyperlinks are not presented in a single form.
The goal of hyper-schemas is a surrogate for that "innate knowledge" which is missing for these home-brew JSON formats.I find schemas (XSD or json-schema) a GREAT way to describe your API contract. JSON-schema also allows to document your actions and links (including those non standard ones). I agree the client will build logic against that API contract (and as such, will build its code based on a given version of the API contract / based on a given schema version.The only thing I struggle with, is expecting the client to download the current version of the schema, at all call, to "detect" changes the server may have decided to undertake, so it can dynamically construct URIs of the links/actions that fits the server implementation. I actually would go further in saying the URI template should not even be part of the schema, it is an implementation details that should be defined outside of the API contract (therefore outside of the schema defining the API contract).
It doesn't have to download the schema. My browser does not fetch "http://www.w3.org/TR/html4/strict.dtd" every time it views a web-page, because it has all the knowledge of that DTD baked into it. However, it still uses that URL (as part of the <DOCTYPE> stuff) to determine the specific details of parsing the page.
Similarly, a custom-written client for a particular API might not fetch "http://example.com/api/schemas/v01" all the time - it might have all the format knowledge baked in, and simply use that URI as an identifier to determine which variation of its interpreter to use.
The advantage comes when one day the API starts returning data referencing the schema "http://example.com/api/schemas/v02", which the client has never seen before. A client relying completely on its own internal knowledge might break at that point. But a client that understands JSON Schemas can be extremely flexible at that point - if it chooses to, it can download the new schema, and make a decent fist of using the new API, instead of just rolling over and dying.
I also envision this flexibility being used to make development easier - during dev/testing phases, you have an extremely generic client that uses JSON Hyper-Schema (using common libraries to do all the interpreting), as you keep chopping and changing the API. Then as you head towards release, you just hard-code a few relevant schemas (so they don't have to be fetched) and go.
I think we talk each other on 2 separate topics. You basically explains me that clients needs knowledge of mime-types to interpret data.
That's all fine and nobody argues that. My point is around the construction of URI. Without breaking the data structure, and therefore without breaking the mime-type interpreter which can continue to interpret the received data, a server may choose to change its implementation to move a resource to another endpoint. In such a scenario you have 3 options:
- The client interpreter hard coded URIs (bad, very bad) to navigate to a related resource: this application is now broken, since server chosen to host the related resource an another endpoint/path
- The client has built logic to retrieve/interpret the URIs by downloading the json-schema (that was somehow associated to the data payload) and read from this schema the URI template associated to the related resource: this application is not broken, continues to work, since the URI template was modified by the server which allows the client to "construct" the URI based on this template. Note that if you had not downloaded (at regular interval) the schema, your client would still attempt to consider the old URI template (that was in place before the server endpoint/path change), and in such case, the client would be broken.
- The client has built logic to retrieve/interpret the URIs directly from the data payload (or the HTTP headers): the application is not broken, since the received URI happens to match the new modified endpoint/path the server chosen to return. The server implementation change (moving the server hosting the resource) is seems-less to the client.
I hope I made my point clearer with this.
Now if the server decides to change the mime-type definition (sending different data all together) and the server cannot serve the former representation which used to be supported prior to that change, then yes, your client would be broken. And even if the client was built to then attempt to download the "new schema" and to "dynamically interpret" the data received makes little sense to me. If you renamed a property, removed another one or added yet another one (or similarly, renamed a "rel", removed one or added another one) your business case is most likely broken. Your client will likely been coded to "do" something with the interpreted data (e.g. build a UI, etc).Maybe I missed your point.
On 15 February 2013 22:41, Philippe Marsteau <mars...@gmail.com> wrote:I think we talk each other on 2 separate topics. You basically explains me that clients needs knowledge of mime-types to interpret data.I'd like to move away from talking about "MIME types", because many APIs of this sort will not have defined their own MIME type. They will be using "application/json", but they will be sending JSON of a certain shape - they will have defined their own constraints on top of JSON.But the MIME type ("application/json") along with the URI of a schema describing the format, together make a "document type" that includes the API-specific JSON dialect.
That's all fine and nobody argues that. My point is around the construction of URI. Without breaking the data structure, and therefore without breaking the mime-type interpreter which can continue to interpret the received data, a server may choose to change its implementation to move a resource to another endpoint. In such a scenario you have 3 options:
- The client interpreter hard coded URIs (bad, very bad) to navigate to a related resource: this application is now broken, since server chosen to host the related resource an another endpoint/path
- The client has built logic to retrieve/interpret the URIs by downloading the json-schema (that was somehow associated to the data payload) and read from this schema the URI template associated to the related resource: this application is not broken, continues to work, since the URI template was modified by the server which allows the client to "construct" the URI based on this template. Note that if you had not downloaded (at regular interval) the schema, your client would still attempt to consider the old URI template (that was in place before the server endpoint/path change), and in such case, the client would be broken.
- The client has built logic to retrieve/interpret the URIs directly from the data payload (or the HTTP headers): the application is not broken, since the received URI happens to match the new modified endpoint/path the server chosen to return. The server implementation change (moving the server hosting the resource) is seems-less to the client.
I hope I made my point clearer with this.Hmm... I think the issue here is that 2 and 3 seem incredibly similar to me.The majority of the time (for RESTful APIs) I would expect the LDO to look something like this:{"href": "{+commentUri}","rel": "create","title:" "Comment",...}Now, that's option 2, because it uses a URI Template. But all that URI Template actually says is "take the URI from the "commentUri" property". It's equivalent to the following client code:function getLinks(data) {if (data.commentUri != undefined) {return [{href: data.commentUri,rel: "create",title: "Create comment"}];}return [];}
That code snippet (if I'm understanding correctly) would count under option 3, because the client is extracting URIs directly from the data payload.So for the case of the server changing URIs: if the API is RESTful, then this requires no change in either the client code or the schema. If the URI Template is a simple one (such as "{+someProperty}") then it does not need to be changed to accomodate the server moving things around - and a client using such a schema will not break.
Now if the server decides to change the mime-type definition (sending different data all together) and the server cannot serve the former representation which used to be supported prior to that change, then yes, your client would be broken. And even if the client was built to then attempt to download the "new schema" and to "dynamically interpret" the data received makes little sense to me. If you renamed a property, removed another one or added yet another one (or similarly, renamed a "rel", removed one or added another one) your business case is most likely broken. Your client will likely been coded to "do" something with the interpreted data (e.g. build a UI, etc).Maybe I missed your point.I think there's a middle-ground. For example, what if the change does not relate to the data being displayed? What if the changes are in:
- The name of the property holding the URIs for certain links (e.g. it used to be called "commentUri", but it's now called "createComment")
- The nature of the data that should be submitted to the server (e.g. it now requires a new parameter "public" which defaults to the value true)
In both cases, the fixed client (case 3) will break. But the schema-driven one (case 2) might choose to re-fetch the schema when it starts getting "400 Bad request" responses - at which point, it will be able to adapt to the changes in the API.
What I'm trying to say is that when the schema is fixed, it is no more or less flexible than a client with the same logic hard-coded.I also would much prefer that my client did something slightly un-smooth than break completely. So in the case of the new "permissions" property - my client could display the same interface as before, but under-the-hood start submitting "public":true. Or alternatively, it might decide to display a checkbox somewhere in the interface. Either option is not as good as a shiny new version of the client that displays a nice styled slider for "public" - but they're both a mile better than just becoming non-functional.
--
You received this message because you are subscribed to a topic in the Google Groups "JSON Schema" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/json-schema/ttXvKdyMLi0/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to json-schema...@googlegroups.com.
I think I'm on-board with that. Based on what you said, it seems that the schema will only contain templated properties that point to other properties in the actual instance. However, I'm still left with some concerns:1. How does this work for nested data in the instance? For example, I would probably want to have a 'link' object in my instance that contains things other than the URI (e.g. HTTP method, media type, etc.). How does the template reference these fields?
2. In practice, how long do you expect clients to 'hold on' to the schema document before refreshing it? I'm assuming freshness information will be controlled by the server and the client just sticks to it?3. While the approach you suggested works, it seems pretty roundabout to me. Clients are redirected from the instance to the schema to retrieve link templates, and then from the schema back to the instance so that they can resolve the templates. I appreciate the need for extensibility, but I'm wondering if that is how we want to proceed for hyperlinks. While JSON Schema is a pretty generic construct that applies to all JSON use cases, JSON Hyper-Schema seems to be something more specialized, and is primarily useful only for REST APIs. Why not just fix the LDO structure (as in the v3 spec), add support for both templated and real hrefs, and have that be used as the schema for links in the instance? Adding LDOs to the instance would be an additive change, so existing APIs (that already contain links) are not really broken. Their clients have 2 options for figuring out how they want to transition their state.
On 26 February 2013 18:39, Abhijit Tambe <tambe....@gmail.com> wrote:I think I'm on-board with that. Based on what you said, it seems that the schema will only contain templated properties that point to other properties in the actual instance. However, I'm still left with some concerns:1. How does this work for nested data in the instance? For example, I would probably want to have a 'link' object in my instance that contains things other than the URI (e.g. HTTP method, media type, etc.). How does the template reference these fields?I was proposing enabling templating for all of those fields. If we used URI Templates, it would be simple to define - but I'm open to other ideas.In my previous example, "rel" was templated as well - you would just copy the same syntax and use it for "mediaType", etc.
2. In practice, how long do you expect clients to 'hold on' to the schema document before refreshing it? I'm assuming freshness information will be controlled by the server and the client just sticks to it?3. While the approach you suggested works, it seems pretty roundabout to me. Clients are redirected from the instance to the schema to retrieve link templates, and then from the schema back to the instance so that they can resolve the templates. I appreciate the need for extensibility, but I'm wondering if that is how we want to proceed for hyperlinks. While JSON Schema is a pretty generic construct that applies to all JSON use cases, JSON Hyper-Schema seems to be something more specialized, and is primarily useful only for REST APIs. Why not just fix the LDO structure (as in the v3 spec), add support for both templated and real hrefs, and have that be used as the schema for links in the instance? Adding LDOs to the instance would be an additive change, so existing APIs (that already contain links) are not really broken. Their clients have 2 options for figuring out how they want to transition their state.This concern about multiple requests is one I hear a lot. The problem is, though, that's it's comparing apples and oranges.On the one hand, we have "baked-in" knowledge of a format (such as a particular link format). On the other hand, we have a schema that defines the format. But just because a schema has been defined does not mean that every client using the data has to fetch the schema and process it.Say, hypothetically, you have written a client that uses a particular API, with hard-coded knowledge about the data formats and embedded links. Then, after you have written and released your client, the API authors document their API using JSON (Hyper-)Schema.At that point - you can totally ignore the schemas if you want. I mean, you already know what's in the data, why would you need to go and fetch a document that tells you what you already know? However, if a new client comes along that does not have that built-in knowledge of the API, then the schema is extremely useful to them.Schemas should only add functionality to those clients that understand them - they should not be required for use of the API, if the client already has special knowledge.