What is the proper schema for JSON-LD telephone number with extension? - schema.org

I'm trying to find the proper schema for telephones with extensions, but I can't find anything related to this problem through Google searches or schema.org.
In HTML, I'm using , to trigger the extension on cellphones and Skype, but I've also seen p used to "pause" between numbers when dialing. Which is the best route in regards to proper JSON-LD schema?
No extension used:
{
"#type": "Organization",
"telephone": "+18665554985"
}
Style 1 using p:
{
"#type": "Organization",
"telephone": "+18665554985p100"
}
Style 2 using ,:
{
"#type": "Organization",
"telephone": "+18665554985,100"
}

The telephone property has Text as expected value. If a specific format should be used, it would be noted in the property’s description, but that’s not the case for telephone.¹
So you can use whichever format you want.
Which format would make sense? I would go with the same format you display for your users (which would ideally be the recommended format according to a convention/standard relevant for the targeted users). This is the natural choice when using Microdata or RDFa to mark it up, and there is no reason to go a different route for JSON-LD. This would also help in cases where a consumer simply displays your value of the telephone property: it will be in the appropriate format for your users.
¹ There was some discussion about this in the issue Make the telephone property more structured (not just Text). I would expect that the expected range will, at some point, include URL values, so that tel URIs can be used (which of course have a specified format).

Related

Providing information ragarding the content of a link target with HAL

We intend to use Spring-HATEOAS to enrich our interface with hypermedia informations via HAL/JSON.
What we are wondering is, how to provide sufficient meta information of what we are going to find in a resource after following a link.
I identified different methods to publish such information, with one being the content type of the resource and the other being a profile.
However both do not allow any kind of polymorphism.
Let's assume we model a weather station which has a temperature a wind and a light sensor.
In my concept I would link those three sensors:
"item" : [
{ "href" : ".../sensors/1" } // temperature
{ "href" : ".../sensors/2" } // wind
{ "href" : ".../sensors/3" } // light
]
which means they are part of my sensor collection (which my weather station is).
To the user of my weather station, I would like to provide the meta information, that:
All three sensors are sensors (which implys the existence of certain properties)
Sensor 1 is a unidirectional sensor, whil 2 and 3 only measure for a specific direction
Sensor 3 provides addtional to the value (intensity) some spectral information.
So in Code:
class TemperatureSensor extends Sensor
class WindSensor extends Sensor implements DirectionalSensor
class LightSensor extends Sensor implements DirectionalSensor, SprectralSensor
How can I provide those information to the user, using Spring-HATEOAS or directly HAL?
I identified different methods to publish such information, with one being the content type of the resource and the other being a profile.
In general the media type defines how to process a payload but not necessarily what object or type its content relates to. I.e. on receiving a HTML payload you don't necessarily know that the page contains user information or the like, unless you have certain semantic annotations present within the markup. All HTML defines is a set of valid elements, how these elements have to be embedded in the payload (i.e. either <element>...</element> or <element/>), which attributes they support and when it is admissible to add which elements, i.e. certain elements such as the list-item tag <li> makes only sense as part of an unordered list <ul> or its counter-part the order list <ol>.
In regards to profiles, according to RFC 6906
A profile is defined not to alter the semantics of the resource representation itself, but to allow clients to learn about additional semantics (constraints, conventions, extensions) that are associated with the resource representation, in addition to those defined by the media type and possibly other mechanisms.
It is therefore a configuration option to set on the media-type processor, which depending on the profile specified, might apply additional validation rules, allow certain elements to appear in certain elements or the like. I.e. HTML4.01 added profiles to the <head> element so that search engines that understand this profile know that meta-information for author, date, keyword and copyright will be present which they can use directly instead of attempting to parse that information from the body directly.
HAL supports both the specification of profiles on media-type definitions as well as on link objects.
... how to provide sufficient meta information of what we are going to find in a resource after following a link.
In HTML a user is usually hinted what invoking a link might return by adding additional text, that summarizes the content of that target, or images, that express an affordance to the user, to the link context. For humans this is usually easy to understand though for an automated process such meta information are usually difficult to process and act upon. Instead of using free-text or images to express the relation the target has to the current content, link relations are used to express this.
According to RFC 8288 (Web Linking)
... an application will define the link relation type(s) it uses, along with the serialisation(s) that they might occur within. For example, the application "Web browsing" looks for the "stylesheet" link relation type in the HTML link serialisation (and optionally in the Link header field), whereas the application "AtomPub" uses the "edit" and "edit-media" link relations in the Atom serialisation.
Web linking also describes that link-relations not only describe simple semantics but also particular attributes or behaviors. More formally, they describe how the current context is related to an other resource.
Wikipedia describes link relations as:
A link relation is a descriptive attribute attached to a hyperlink in order to define the type of the link, or the relationship between the source and destination resources. The attribute can be used by automated systems, or can be presented to a user in a different way.
Such link relations should be based on standardized terms or make use of an extension mechanism, i.e. dublin-core. Microformats also lists plenty of commonly used relation names in HTML5. While link-relations must not constrain the processing of the current document or the availability of target representation types, they can specify certain behaviors or properties of target resources, i.e. that a resource supports certain HTTP methods or that support of certain media-type formats is required.
A link may have multiple different link relation names assigned. Clients that do not understand a certain link relation name should ignore it and only operate on those they do know and support. This basically just allows to add as many relation names to the URI context as needed. This is similar to the semantic Web where there may exist multiple predicates between a subject and object and further relation exist that indicate that a predicate expresses the same as an other one and may thus be used interchangingly.
HAL supports link-relations out of the box and adds CURIEs on top, which is a further reserved link-relation name itself, that hints a client on the location of a resource documentation. Link relation extension, as defined by RFC 8288, do not necessarily need to point to a documentation describing the semantics, therefore clients shouldn't access such URIs by default.
A links-section within a HAL representation response may look like this for the given problem statement:
...
"links": {
"self": { "href": "/weatherstation" },
"curies": [{ "name": "ws", "href": "http://api.weatherstation.com/docs/rels/{rel}", "templated": true }],
"ws:sensors": [
{ "href": "../sensors/1", "title": "temperature" },
{ "href": "../sensors/2", "title": "wind" },
{ "href": "../sensors/3", "title": "light" }
],
"ws:unidirectional": { "href": "../sensors/1", "title": "temperature" },
"ws:directional": [
{ "href": "../sensors/2", "title": "wind" },
{ "href": "../sensors/3", "title": "light" }
],
"ws:spectral": { "href": "../sensors/3", "title": "light" },
...
"http://api.weatherstation.com/rel/sensors": [
{ "href": "../sensors/1" },
{ "href": "../sensors/2" },
{ "href": "../sensors/3" }
],
"http://api.weatherstation.com/rel/unidirectional": { "href": "../sensors/1" },
"http://api.weatherstation.com/rel/directional": [
{ "href": "../sensors/2" },
{ "href": "../sensors/3" }
],
"http://api.weatherstation.com/rel/spectral": { "href": "../sensors/3" }
}
At this point I'm not 100% sure whether Curies also express link-relations or just express the documentation of a resource, hence I divided the sample above a bit. In theory they should be able to be valid link-relation names itself, in which case the latter definition may be skipped, as the HAL processor will resolve them to a full URI as required by RFC 8288 anyway.
While Web linking would allow for a link-relation such as:
Link: <../sensors/3>; rel="http://api.weatherstation.com/rel/sensors http://api.weatherstation.com/rel/directional http://api.weatherstation.com/rel/spectral"
that defines all 3 attributes on the same URI, I'm not sure if this is also possible in HAL directly.
Support for Curies is documented in the reference documentation where you basically just have to add a CurieProvider bean to your config. This Curie provider kicks in on all non registered link relations you define via RelProvider. Registered link relations can easily be added via new Link("/some-target", IanaLinkRelations.NEXT) for example as documented here

REST - boolean parameters naming conventions

What are the standards for boolean parameters in REST which indicates whether or not certain parts of the response should be included. Should they be prefixed with "include" "with" or similar prefix?
Example:
Say, I have a REST service GET /buildings which returns buildings:
[
{
name: "The Empire State Building",
flors: 102
}
]
Now when there is a use case to include the address, but the address is not always needed (because let's say getting address is quite expensive in the backend, so it is better not to include that by default).
I would like to add parameter which instructs the backend to include address in response, say:
GET /buildings?address=true:
[
{
"name": "The Empire State Building",
"flors": 102,
"address": {
"street" : "Fifth Avenue",
"number": 99
}
}
]
Now the question is how this address parameter should be named:
"includeAddress=true", "address=true"or what should be the name?
Now the question is how this address parameter should be named: "includeAddress=true", "address=true"or what should be the name?
REST doesn't care what spelling you use for your identifiers, outside of the spelling restrictions placed on URI (for example, reserved characters)
From the point of view of generic HTTP components, /buildings and /buildings?address=true are two different, unrelated, resources.
So the choice of includeAddress vs address vs 3e8f8e8b-149a-430f-9c9d-e13c570ff8e4 is really left to your local naming conventions. The machines don't care, but humans take some comfort from consistency, familiarity, and so on.
Think of them like variable names in your code - the compiler/interpreter doesn't care, so long as your spellings respect the language syntax. But your colleagues will expect the spellings to confirm to the local style guide.
GET /buildings?address=true sounds like a query that filters for buildings that have addresses. But that is not what you want to say.
I'd use matrix parameters like this:
# Include the address information
GET /buildings;include=address
# Include the address and insurance information
GET /buildings;include=address,insurance

Schema.org data structure for transport system

I'm trying to classify a number of transport systems. I would like to use Schema.org markup but I can not find a category that covers these items.
I guess I need to create a custom "object". Can anyone give me a simple example of how to mark up my content?
The information could be like this:
Item: London Underground
City: London
Type: Metro
Number of lines: 10
Number of stations: 10
Basic fare: 1
Schedule: 00:00 - 23:00
…
Another one:
Item: Barcelona Bus Network
City: Barcelona
Type: Bus
Number of lines: 15
Number of stations: 200
…
You can't create a custom object the way you are asking, I believe you can get by using schema.org's Service though. Schema has some more specific service types, if each transport system in your list is government maintained, then perhaps you could use Government Service.
As far as how to mark up your content, you first need to decide how you want to add schema (e.g. microdata, RDFa, JSON-LD). The schema.org site has general examples that should help point you in the right direction on how to write one of those three. Here's an example code of a general service
I leave my answer, it can be useful to someone no matter how much time has passed.
The transport service has to be added under the service scheme. But if you don't want to leave out your local business, you can add that business as a service provider.
Here is an example of how it should be done.
{
"#context": "https://schema.org/",
"#type": "Service",
"provider": {
"#type": "LocalBusiness",
"name": "Litoral Trans"
},
"areaServed": {
"#type": "Status",
"name": "Santa Fe"
},
...
}
You can find good examples at the end of the following link https://schema.org/Service

Master-detail representation in Json-LD

On forhand : sorry if I misunderstood hypermedia or Restfull concepts : it's a work in progress...)
I try to figure out hypermedia and hydra (http://www.markus-lanthaler.com/hydra), and have some questions about returning information to the client before designing my api.
say I have a webshop located at www.myshop.com
a HTTP GET to the root could return (for example) a list of resources represented as link (in a json-ld document):
...
"#id": "/api",
"products" : "www.myshop.com/api/products",
"customers":"www.myshop.com/api/customers"
...
First question on hydra, how could I add actions here ? it seems the client needs to load another document before the load of application. I mean the potential actions are not in the docuemnt retrieved from www.myshop.com/api Or do I miss something?
Then going further, I've stated that products is a hydra:Link so that the client could follow that link (interact with it) with a HTTP GET and retrieve a list of products. that will be a list like this :
....
{
"#id": "/api/products/123",
"#type": "vocab:Product"
},
{
"#id": "/api/products/124",
"#type": "vocab:Product"
},
....
here the client receives a list of product (That could be a paged collection). But if the client wants to display it to the user, let's say a table with [product Id, price, name] (not all Product's properties)
Second Question : How could I do that without the client sending a request to the server for each product, but still provide the link to get the product's detailed information,(or even here having four link : one for getting the detailed information, one for Delete and one for sharing it with a friend and a last one to add it to a Basket) ?
In fact I have difficulties to figure out how hydra is coming into play by not having Links in the document itself? I think that Hal uses this approach to having links in the document itself (if I am right) and I try to find how hydra does this link...
regards
A bit late but I'll nevertheless try to answer your questions Cedric.
say I have a webshop located at www.myshop.com
a HTTP GET to the root could return (for example) a list of resources
represented as link (in a json-ld document):
... "#id": "/api",
"products" : "www.myshop.com/api/products",
"customers":"www.myshop.com/api/customers" ...
First question on hydra, how could I add actions here ? it seems the
client needs to load another document before the load of application.
I mean the potential actions are not in the docuemnt retrieved from
www.myshop.com/api Or do I miss something?
You basically have two options here: 1) embed the operations directly in the response or 2) attach the operations to the properties (products, customers) instead.
Approach 1) would look somewhat like this:
...
"#id": "/api",
"products" : {
"#id": "http://www.myshop.com/api/products",
"operation": {
"#type": "Operation",
"method": "POST",
"expects": "Product"
}
}
...
While approach 2) would attach the same operation to the products property in the referenced Hydra ApiDocumentation:
...
"#id": "...products",
"supportedOperation": {
"#type": "Operation",
"method": "POST",
"expects": "Product"
}
...
Please note that in 1) I used operation while in 2) I used supportedOperation. Also, you should use a more specific type than Operation.
Regarding your second question:
with a HTTP GET and retrieve a list of products. that will be a list like this :
....
{
"#id": "/api/products/123",
"#type": "vocab:Product"
},
{
"#id": "/api/products/124",
"#type": "vocab:Product"
},
....
here the client receives a list of product (That could be a paged
collection). But if the client wants to display it to the user, let's
say a table with [product Id, price, name] (not all Product's
properties)
Second Question: How could I do that without the client sending a
request to the server for each product, but still provide the link to
get the product's detailed information,(or even here having four link
: one for getting the detailed information, one for Delete and one for
sharing it with a friend and a last one to add it to a Basket) ?
You can add as much information (including links) as you want directly in the collection.
....
{
"#id": "/api/products/123",
"#type": "vocab:Product",
"name": "Product 123",
"price": "9.99"
},
{
"#id": "/api/products/124",
"#type": "vocab:Product",
"name": "Product 124",
"price": "19.99"
},
....
That way, a client only needs to dereference an item if the collection doesn't contain that required information.
In fact I have difficulties to figure out how hydra is coming into
play by not having Links in the document itself?
Of course you do have links in the document as well. Links are just properties whose values happen to be URLs (objects with an #id property unless you set the property's type to #id in the context to get rid of that) instead of treating them specially.
note: The Hydra part of the answers I am not so sure, the JSON-LD and REST are okay I think.
You can use #base and relative IRIs by JSON-LD, or you can define namespaces in the #context, so after that you can use relative IRIs as ns:relativeIRI. Each one is better than returning the full IRI. (It is easier to parse the results with a general JSON-LD parser on client side, instead of a simple JSON parser.)
You can define your own #vocab using the Hydra vocab, or you can add "action" definitions in the #context. If you want to "add actions" you have to use hydra:Operation sub-classes in your vocab. Something like this (but I am not a Hydra expert):
{
"#id": "vocab:ProductList",
//...
"hydra:supportedOperations": [
{
"#type": "hydra:CreateResourceOperation",
"method": "POST",
"expects": "vocab:Product"
}
//...
]
}
In general by REST, if you need the same resource with fewer properties, then you have to add a new IRI for that resource, e.g.: /myresource?fewer=1. For example in your case: /api/products/?fields="id, price, name" is okay.
By Hydra you have 2 choices if you want multiple links; you can add a new hydra:Link as a property, or you can add a new hydra:Operation as a supportedOperation with method: GET. I guess get operations are for something like search which has an user input, but if you don't want to add a new property for each link, I think you have no other option.
Actually Hydra does have link and operation support. Maybe it is not clear, but JSON-LD is an RDF format, you can define RDF triples in that. So the IRIs you used for example by "customers":"www.myshop.com/api/customers" are just resource identifiers and not links. A link should have IRI, title, method(GET), language, content-type, iana:relation, etc... so it is not possible to describe a link you can follow with just a single IRI (resource identifier). By processing a REST resource a client should never check the IRI structure to know how to display what it got from you. You have to check the other properties of the links, especially iana:relations or by Hydra maybe operation type to do that. So for example in your case www.myshop.com/api/dav8ufg723udvbquacvd723fudvg is a perfectly valid IRI for the list of the customers. We use nice IRIs only because it is easier to configure generate them on server side, and configure a router for them.
Please check the Hydra vocab before further questions. As you can see a Class can have supportedOperations and supportedProperties which are both collections. A Link is a Property sub-class which can have a single Operation. By collections I think you have to use the Collection class, in which member contains the items of the collection... Be aware that by JSON-LD there is no difference by defining a single item or multiple items with the same type. In the context you have to define only the type, and the value of the property can contain both a single item or an array of items... If you want some constraints about that I guess you have to add some OWL triples, and a validator which checks the values using them.

Additional fields (author, isbn) for /{user}/books.reads

Introduction
/me/books.reads returns books[1].
It includes an array of books and the following fields for each book:
title
type
id
url
Problem
I'd like to get the author name(s) at least. I know that written_by is an existing field for books.
I'd like to get ISBN, if possible.
Current situation
I tried this:
/me/books.reads?fields=data.fields(author)
or
/me/books.reads?fields=data.fields(book.fields(author))
But the error response is:
"Subfields are not supported by data"
The books.reads response looks like this (just one book included):
{
"data": [
{
"id": "00000",
"from": {
"name": "User name",
"id": "11111"
},
"start_time": "2013-07-18T23:50:37+0000",
"publish_time": "2013-07-18T23:50:37+0000",
"application": {
"name": "Books",
"id": "174275722710475"
},
"data": {
"book": {
"id": "192511337557794",
"url": "https://www.facebook.com/pages/A-Semantic-Web-Primer/192511337557794",
"type": "books.book",
"title": "A Semantic Web Primer"
}
},
"type": "books.reads",
"no_feed_story": false,
"likes": {
"count": 0,
"can_like": true,
"user_likes": false
},
"comments": {
"count": 0,
"can_comment": true,
"comment_order": "chronological"
}
}
}
If I take the id of a book, I can get its metadata from the open graph, for example http://graph.facebook.com/192511337557794 returns something like this:
{
"category": "Book",
"description": "\u003CP>The development of the Semantic Web...",
"genre": "Computers",
"is_community_page": true,
"is_published": true,
"talking_about_count": 0,
"were_here_count": 0,
"written_by": "Grigoris Antoniou, Paul Groth, Frank Van Harmelen",
"id": "192511337557794",
"name": "A Semantic Web Primer",
"link": "http://www.facebook.com/pages/A-Semantic-Web-Primer/192511337557794",
"likes": 1
}
The response includes ~10 fields, including written_by which has the authors of the book.
Curiously, link field seems to map to url of the books.reads response. However, the field names are different, so I'm starting to loose hope that I would be able to ask for written_by in books.reads request..
The only reference that I've found about /me/books is https://developers.facebook.com/docs/reference/opengraph/object-type/books.book/
This is essentially about user sharing that he/she has read a book, not the details of the book itself.
The data structure is focused on the occasion of reading a book: when reading was started, when this story was published, etc.
[1] I know this thanks to How to get "read books"
FQl does not looks very promising – although you can request books from the user table, it seems to deliver just a string value with only the book titles comma-separated.
You can search page table by name – but I doubt it will work with name in (subquery) when what that subquery delivers is just one string of the format 'title 1,title 2,…'.
Can’t really test this right now, because I have read only one book so far (ahm, one that I have set as “books I read” on FB, not in general …) – but using that to search the page table by name already delivers a multitude of pages, and even if I narrow that selection down by AND is_community_page=1, I still get several, so no real way of telling which would be the right one, I guess.
So, using the Graph API and a batch request seems to be more promising.
Similar to an FQL multi-query, batch requests also allow you to refer data from the previous “operation” in a batch, by giving operations a “name”, and then referring to data from the first operation by using JSONPath expression format (see Specifying dependencies between operations in the request for details).
So a batch query for this could look like this,
[
{"method":"GET","name":"get-books","relative_url":"me\/books?fields=id"},
{"method":"GET","relative_url":"?ids={result=get-books:$.data.*.id}
&fields=description,name,written_by"}
]
Here all in one line, for easier copy&paste, so that line breaks don’t cause syntax errors:
[{"method":"GET","name":"get-books","relative_url":"me\/books?fields=id"},{"method":"GET","relative_url":"?ids={result=get-books:$.data.*.id}&fields=description,name,written_by"}]
So, to test this:
Go to Graph API Explorer.
Change method to POST via the dropdown, and clear whatever is in the field right next to it.
Click “Add a field”, and input name batch, and as value insert the line copy&pasted from above.
Since that will also get you a lot of “headers” you might not be interested in, you can add one more field, name include_headers and value false to get rid of those.
In the result, you will get a field named body, that contains the JSON-encoded data for the second query. If you want more fields, add them to the fields parameter of the second query, or leave that parameter out completely if you want all of them.
OK, after some trial-and-error I managed to create a direct link to Graph API Explorer to test this – the right amount of URL-encoding to use is a little fiddly to figure out :-)
(I left out the fields parameter for the second operation here, so this will give you all the info for the book that there is.)
As I said, I only got one book on FB, but this should work for a user with multiple books the same way (since the second operation just takes however many IDs it is given from the first one).
But I can’t tell you off the top of my head how this will work for a lot of books – how slow the second operation might get with that, when you set a high limit for the first one. And I also don’t know how this will behave in regard to pagination, which you might run into when me/books delivers a lot of books for a user.
But I think this should be a good enough starting point for you to figure the rest out by trying it on users with more data. HTH.
Edit: ISBN does not seem to be part of the info for a book’s community page, at least not for the ones I checked. And also written_by is optional – my book doesn’t have it. So you’ll only get that info if it is actually provided.