Schema.org is basically a simple vocabulary for describing stuff, on the web. Embed it in your html and the search engines will pick it up as they crawl, and add it to their structured data knowledge graphs. They even give you three formats to chose from — Microdata, RDFa, and JSON-LD — when doing the embedding. I’m assuming, for this post, that the benefits of being part of the Knowledge Graphs that underpin so called Semantic Search, and hopefully triggering some Rich Snippet enhanced results display as a side benefit, are self evident.

The vocabulary itself is comparatively easy to apply once you get your head around it — find the appropriate Type (Person, CreativeWork, Place, Organization, etc.) for the thing you are describing, check out the properties in the documentation and code up the ones you have values for. Ideally provide a URI (URL in Schema.org) for a property that references another thing, but if you don’t have one a simple string will do.

There are a few strangenesses, that hit you when you first delve into using the vocabulary. For example, there is no problem in describing something that is of multiple types — a LocalBussiness is both an Organisation and a Place. This post is about another unusual, but very useful, aspect of the vocabulary — the Role type.

At first look at the documentation, Role looks like a very simple type with a handful of properties. On closer inspection, however, it doesn’t seem to fit in with the rest of the vocabulary. That is because it is capable of fitting almost anywhere. Anywhere there is a relationship between one type and another, that is. It is a special case type that allows a relationship, say between a Person and an Organization, to be given extra attributes. Some might term this as a form of annotation.

So what need is this satisfying you may ask. It must be a significant need to cause the creation of a special case in the vocabulary. Let me walk through a case, that is used in a Schema.org Blog post, to explain a need scenario and how Role satisfies that need.

Starting With American Football

Say you are describing members of an American Football Team. Firstly you would describe the team using the SportsOrganization type, giving it a name, sport, etc. Using RDFa:

<div vocab="http://schema.org/" typeof="SportsOrganization" resource="http://example.com/teams/tlg"> <span property="name">Touchline Gods</span> <span property="sport">American Football</span> </div> 1 2 3 4 <div vocab = "http://schema.org/" typeof = "SportsOrganization" resource = "http://example.com/teams/tlg" > <span property = "name" > Touchline Gods </span> <span property = "sport" > American Football </span> </div>

Then describe a player using a Person type, providing name, gender, etc.:

Team Member <div vocab="http://schema.org/" typeof="Person" resource="http://example.com/folks/chucker"> <span property="name">Chucker Roberts</span> <span property="birthDate">1989</span> </div> 1 2 3 4 <div vocab = "http://schema.org/" typeof = "Person" resource = "http://example.com/folks/chucker" > <span property = "name" > Chucker Roberts </span> <span property = "birthDate" > 1989 </span> </div>

Now lets relate them together by adding an athlete relationship to the Person description:

<div vocab="http://schema.org/" typeof="SportsOrganization"> <span property="name">Touchline Gods</span> <span property="sport">American Football</span> <span property="athlete" typeof="Person" src="http://example.com/folks/chucker"> <span property="name">Chucker Roberts</span> <span property="birthDate">1989</span> </span> </div> 1 2 3 4 5 6 7 8 <div vocab = "http://schema.org/" typeof = "SportsOrganization" > <span property = "name" > Touchline Gods </span> <span property = "sport" > American Football </span> <span property = "athlete" typeof = "Person" src = "http://example.com/folks/chucker" > <span property = "name" > Chucker Roberts </span> <span property = "birthDate" > 1989 </span> </span> </div>

Let’s take a look of the data structure we have created using Turtle – not a html markup syntax but an excellent way to visualise the data structures isolated from the html:

@prefix schema: <http://schema.org/> . <http://example.com/teams/tlg> a schema:SportsOrganization; schema:name "Touchline Gods"; schema:sport "American Football"; schema:athlete <http://example.com/folks/chucker> . <http://example.com/folks/chucker> a schema:Person; schema:name "Chucker Roberts"; schema:birthDate "1969". 1 2 3 4 5 6 7 8 9 10 11 12 @ prefix schema : < http : //schema.org/> . < http : //example.com/teams/tlg> a schema : SportsOrganization ; schema : name "Touchline Gods" ; schema : sport "American Football" ; schema : athlete < http : //example.com/folks/chucker> . < http : //example.com/folks/chucker> a schema : Person ; schema : name "Chucker Roberts" ; schema : birthDate "1969" .

So we now have Chucker Roberts described as an athlete on the Touchline Gods team. The obvious question then is how do we describe the position he plays in the team. We could have extended the SportsOrganization type with a property for every position, but scaling that across every position for every team sport type would have soon ended up with far more properties than would have been sensible, and beyond the maintenance scope of a generic vocabulary such as Schema.org.

This is where Role comes in handy. Regardless of the range defined for any property in Schema.org, it is acceptable to provide a Role as a value. The convention then is to use a property with the same property name, that the Role is a value for, to then remake the connection to the referenced thing (in this case the Person). In simple terms we have have just inserted a Role type between the original two descriptions.

This indirection has not added much you might initially think, but Role has some properties of its own (startDate, endDate, roleName) that can help us qualify the relationship between the SportsOrganization and the athlete (Person). For the field of organizations there is a subtype of Role (OrganizationRole) which allows the relationship to be qualified slightly more.

RDFa:

<div vocab="http://schema.org/" typeof="SportsOrganization" resource="http://example.com/teams/tlg"> <span property="name">Touchline Gods</span> <span property="sport">American Football</span> <span property="athlete" typeof="OrganizationRole"> <span propery="startDate">2014-07-01</span> <span property="roleName">Quarterback</span> <span property="number">11;</span> <span property="athlete" typeof="Person" src="http://example.com/folks/chucker"> <span property="name">Chucker Roberts</span> <span property="birthDate">1989</span> </span> </span> </div> 1 2 3 4 5 6 7 8 9 10 11 12 13 <div vocab = "http://schema.org/" typeof = "SportsOrganization" resource = "http://example.com/teams/tlg" > <span property = "name" > Touchline Gods </span> <span property = "sport" > American Football </span> <span property = "athlete" typeof = "OrganizationRole" > <span propery = "startDate" > 2014-07-01 </span> <span property = "roleName" > Quarterback </span> <span property = "number" > 11; </span> <span property = "athlete" typeof = "Person" src = "http://example.com/folks/chucker" > <span property = "name" > Chucker Roberts </span> <span property = "birthDate" > 1989 </span> </span> </span> </div>

and in Turtle:

@prefix schema: <http://schema.org/> <http://example.com/teams/tlg> a schema:SportsOrganization; schema:name "Touchline Gods"; schema:sport "American Football"; schema:athlete [ a schema:OrganizationRole schema:roleName "Quarterback"; schema:startDate "2014-07-01"; schema:number "11" schema:athlete <http://example.com/folks/chucker> ]. <http://example.com/folks/chucker> a schema:Person; schema:name "Chucker Roberts"; schema:birthDate "1969" . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @ prefix schema : < http : //schema.org/> < http : //example.com/teams/tlg> a schema : SportsOrganization ; schema : name "Touchline Gods" ; schema : sport "American Football" ; schema : athlete [ a schema : OrganizationRole schema : roleName "Quarterback" ; schema : startDate "2014-07-01" ; schema : number "11" schema : athlete < http : //example.com/folks/chucker> ] . < http : //example.com/folks/chucker> a schema : Person ; schema : name "Chucker Roberts" ; schema : birthDate "1969" .

Beyond American Football

So far I have just been stepping through the example provided in the Schema.org blog post on this. Let’s take a look at an example from another domain – the one I spend my life immersed in – libraries.

There are many relationships between creative works that libraries curate and describe (books, articles, theses, manuscripts, etc.) and people & organisations that are not covered adequately by the properties available (author, illustrator, contributor, publisher, character, etc.) in CreativeWork and its subtypes. By using Role, in the same way as in the sports example above, we have the flexibility to describe what is needed.

Take a book (How to be Orange: an alternative Dutch assimilation course) authored by Gregory Scott Shapiro, that has a preface written by Floor de Goede. As there is no writerOfPreface property we can use, the best we could do is to is to put Floor de Goede in as a contributor. However by using Role can qualify the contribution role that he played to be that of the writer of preface.

In Turtle:

@prefix schema: <http://schema.org/> . @prefix relators: <http://id.loc.gov/vocabulary/relators/> . @prefix viaf: <http://viaf.org/viaf/> . <http://www.worldcat.org/oclc/859406554> a schema:Book; schema:name "How to be orange : an alternative Dutch assimilation course"; schema:author viaf:305830120; # Gregory Scott Shapiro schema:exampleOfWork <http://worldcat.org/entity/work/id/1404771725>; schema:contributor [ a schema:Role; schema:roleName relators:wpr; # Writer of preface schema:contributor viaf:283191359; # Floor de Goede ] . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @ prefix schema : < http : //schema.org/> . @ prefix relators : < http : //id.loc.gov/vocabulary/relators/> . @ prefix viaf : < http : //viaf.org/viaf/> . < http : //www.worldcat.org/oclc/859406554> a schema : Book ; schema : name "How to be orange : an alternative Dutch assimilation course" ; schema : author viaf : 305830120 ; # Gregory Scott Shapiro schema : exampleOfWork < http : //worldcat.org/entity/work/id/1404771725>; schema : contributor [ a schema : Role ; schema : roleName relators : wpr ; # Writer of preface schema : contributor viaf : 283191359 ; # Floor de Goede ] .

and RDFa:

<div vocab="http://schema.org/" typeof="Book" resource="http://www.worldcat.org/oclc/859406554"> <span property="name">How to be orange : an alternative Dutch assimilation course</span> <span property="author" src="http://viaf.org/viaf/305830120">Gregory Scott Shapiro</span> <span property="exampleOfWork" src="http://worldcat.org/entity/work/id/1404771725"></span> <span property="contributor" typeOf="Role" > <span property="roleName" src="http://id.loc.gov/vocabulary/relators/wpr">Writer of preface</span> <span property="contributor" src="http://http://viaf.org/viaf/283191359">Floor de Goede</span> </span> </div> 1 2 3 4 5 6 7 8 9 <div vocab = "http://schema.org/" typeof = "Book" resource = "http://www.worldcat.org/oclc/859406554" > <span property = "name" > How to be orange : an alternative Dutch assimilation course </span> <span property = "author" src = "http://viaf.org/viaf/305830120" > Gregory Scott Shapiro </span> <span property = "exampleOfWork" src = "http://worldcat.org/entity/work/id/1404771725" > </span> <span property = "contributor" typeOf = "Role" > <span property = "roleName" src = "http://id.loc.gov/vocabulary/relators/wpr" > Writer of preface </span> <span property = "contributor" src = "http://http://viaf.org/viaf/283191359" > Floor de Goede </span> </span> </div>

You will note in this example I have made use of URLs, to external resources – VIAF for defining the Persons and the Library of Congress relator codes – instead of defining them myself as strings. I have also linked the book to it’s Work definition so that someone exploring the data can discover other editions of the same work.

Do I always use Role?

In the above example I relate a book to two people, the author and the writer of preface. I could have linked to the author via another role with the roleName being ‘Author’ or <http://id.loc.gov/vocabulary/relators/aut>. Although possible, it is not a recommended approach. Wherever possible use the properties defined for a type. This is what data consumers such as search engines are going to be initially looking for.

One last example

To demonstrate the flexibility of using the Role type here is the markup that shows a small diversion in my early career:

@prefix schema: <http://schema.org/> . <http://www.wikidata.org/entity/Q943241> a schema:PerformingGroup; schema:name "Gentle Giant"; schema:employee [ a schema:Role; schema:roleName "Keyboards Roadie"; schema:startDate "1975"; schema:endDate "1976"; schema:employee [ a schema:Person; schema:name "Richard Wallis"; ]; ]; . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @ prefix schema : < http : //schema.org/> . < http : //www.wikidata.org/entity/Q943241> a schema : PerformingGroup ; schema : name "Gentle Giant" ; schema : employee [ a schema : Role ; schema : roleName "Keyboards Roadie" ; schema : startDate "1975" ; schema : endDate "1976" ; schema : employee [ a schema : Person ; schema : name "Richard Wallis" ; ] ; ] ; .

This demonstrates the ability of Role to be used to provide added information about most relationships between entities, in this case the employee relationship. Often Role itself is sufficient, with the ability for the vocabulary to be extended with subtypes of Role to provide further use-case specific properties added.

Whenever possible use URLs for roleName

In the above example, it is exceedingly unlikely that there is a citeable definition on the web, I could link to for the roleName. So it is perfectly acceptable to just use the string “Keyboards Roadie”. However to help the search engines understand unambiguously what role you are describing, it is always better to use a URL. If you can’t find one, for example in the Library of Congress Relater Codes, or in Wikidata, consider creating one yourself in Wikipedia or Wikidata for others to share. Another spin-off benefit for using URIs (URLs) is that they are language independent, regardless of the language of the labels in the data the URI always means the same thing. Sources like Wikidata often have names and descriptions for things defined in multiple languages, which can be useful in itself.

Final advice

This very flexible mechanism has many potential uses when describing your resources in Schema.org. There is always a danger in over using useful techniques such as this. Be sure that there is not already a way within Schema, or worth proposing to those that look after the vocabulary, before using it.

Good luck in your role in describing your resources and the relationships between them using Schema.org