OpenAPI (Swagger), the API Economy, REST, and a Semantic Web of Linked Data
Situation Analysis
The network commonly referred to as the World Wide Web (“Web”) is built upon the powerful duality delivered by a HTTP URI (“Hyperlink”).
One Hyperlink packs two powerful features:
- Denotation —referent signification using a symbol
- Connotation — referent description using a form of media (for instance, a document)
The Hyperlink that brings you to this post demonstrates Medium’s use of said Hyperlink as the document’s name; i.e., how it identifies this document.
A Name is always about the dual act of denotation and connotation via some form of indirection. In the real-world, this denotation → connotation indirection happens in our minds, while on the Web it occurs by way of hyperlinks that return documents (with negotiable content-type).
Hypermedia (Webby Content or Data)
Hypermedia (Webby Content) is Document Content that includes hyperlinks, which may or may not include explicit controls for Hyperlink lookup (or dereference).
For instance, an HTML document is an example of a Hypermedia resource equipped with explicit controls that inform a User Agent about Hyperlink-lookup — in this case, the <a />
tag. The fact that instructions and content are intermingled is what makes HTML a Markup Language, rather than an Abstract Language (e.g., RDF where information is relayed by way of relation relationship-type semantics defined by vocabularies and ontologies).
Notations for creating RDF document content (e.g., RDF-Turtle, JSON-LD) don’t include explicit Hyperlink-lookup controls. Why? For the following reasons:
- Both are notations for constructing RDF Language sentence using subject → predicate → object structure. Thus, the role-semantics of sentence subject, predicate, or objects are the keys to understanding what’s encoded in a sentence (just like the real-world).
- When Linked Data principles are applied, both notations enable the use of hyperlinks to identify the subject and predicate (and optionally, object) of an RDF sentence/statement.
- RDF in its most basic form is driven by a foundation vocabulary (that all RDF-aware applications must understand) with regard to the nature of a sentence, i.e., its subject, predicate, and object components.
- The sophistication of the information encoded in an RDF Language sentence is a function of the vocabulary of terms applied (again, just like the real-world, where the vocabulary of a three-year-old would differ significantly from that of an adult).
Here’s a visualization of a snippet of statements from RDF’s foundation vocabulary, with emphasis on the description of terms such as rdf:subject
, rdf:predicate
, and rdf:object
.
REST Interaction Pattern
As stated earlier, the Web is fundamentally a publicly accessible network where every de-referenceable node on the network is identified by a Hyperlink. Thus, Agents and Servers can exchange information intelligently by guided de-reference (lookup) of relevant segments of hypermedia.
For Agents in particular, this provides a powerful mechanism for application state transition; i.e., the results of Hyperlink lookups actually drive the state transitions a user perceives as application behavior.
REST Vs. A Semantic Web of Linked Data — An Artificial Dichotomy
Unfortunately, a false dichotomy has arisen across the communities of so-called “Web Developers” (who prefer explicit Hyperlink-lookup controls) and don’t necessarily see a need for HTTP URI opacity.
Here is the world-view associated with so-called “Semantic Web Developers” who prefer to leave understanding the nature of controls to context provided by RDF sentences.
Like all paradoxes, Tim Berners-Lee and Roy Fielding aren’t contradicting one another. In fact, they are speaking about different things that are mutually compatible, i.e., denotation and connotation with regard to HTTP!
Anyway, sticking with my solution focus in this post, the issue outlined above is beginning to reach a point of resolution, thanks to the obvious need to document Web APIs (what “Web Developers” are interested in) without covertly imposing the English Language on every developer.
API Documentation
In recent times, Swagger (now known as OpenAPI) has emerged as an open standard for Web API documentation. Its adoption by API publishers has already reached the point of critical mass.
Using a Smart Agent to bridge between REST APIs and the Semantic Web of Linked Data
The remainder of this post demonstrates how API documentation can effectively bridge the artificially separated communities of “Web Developers” and “Semantic Web Developers.”
The tools used in this exercise are:
- OpenLink Smart Data Bot — a Smart Agent that dynamically generates interaction interfaces for both humans and machines via webby data (a/k/a Linked Data) derived from APIs documented using Swagger (specifically, JSON Content-Type)
- Terms from the RDF and Schema.org vocabularies
- URIBurner Service — a live instance of Virtuoso (our platform for modern data access, integration, virtualization, and management) that has the Linked Data module (a/k/a the “Sponger”) enabled
- OpenLink Data Explorer (ODE) browser extension — adds Linked Data transformation services to existing Web Browsers
- OpenLink Structured Data Sniffer (OSDS) — discovers and expose Structured Metadata embedded in HTML documents
- DBpedia — the kernel that spawned the massive Linked Open Data Cloud enclave within the World Wide Web
- A DBpedia Query API — documented using Swagger (actual JSON documentation is right here) and published via Swagger Hub
Generating API Description from Swagger API Documentation
Having an RDF-based Linked Data transformation of an API documented using Swagger implies the following:
- A document exists at a Location identified by a URL on the Web. In this case, URIBurner is the document server — so the URL is grounded in that domain, i.e., http://linkeddata.uriburner.com/about/html/https://api.swaggerhub.com/apis/DBpedia/Virtuoso/1.0.0
- A URI also exists that explicitly identifies the API described by the description derived from Swagger. This identifier is also grounded in the URIBurner domain, i.e., http://linkeddata.uriburner.com/about/id/entity/https/api.swaggerhub.com/apis/DBpedia/Virtuoso/1.0.0
Recalling my earlier points about denotation and connotation, this is why looking-up (clicking or de-referencing) the two aesthetically distinct HTTP URIs above lead to the same content being presented in your browser. Here’s additional information to emphasize this very important point:
- http://linkeddata.uriburner.com/about/id/entity/https/api.swaggerhub.com/apis/DBpedia/Virtuoso/1.0.0 — a URI that identifies the API while also exhibiting denotation & connotation duality by way of indirection (again: this is HTTP URI’s built-in killer-feature and is the reason we have a World Wide Web)
- http://linkeddata.uriburner.com/about/html/https://api.swaggerhub.com/apis/DBpedia/Virtuoso/1.0.0 — a URL (actually a kind [or subcategory] of URI) that identifies a Document (Content Container Location)
OpenLink Smart Data Bot (OSDB) Binding
Now that we have an HTTP URI that unambiguously identifies an API, we can use that URI for all subsequent references, e.g., when loading it into OSDB, as in the depiction below.
Once the description of the API has been processed by OSDB, it is added to the list of registered Web Services (“Services”), and from this point on, you simply click for further guidance.
Here’s a list of options (“arguments”) available to a human or software agent seeking to interact with a specific Action (labeled “find_related_dbpedia_resources_for_a_given_string”) associated with a registered Service (labeled “dbpedia_query_api”) using OSDB.
Here’s an interaction console (oriented to the human user) that provides one interaction option.
Note: All default values and help-text are generated from the API description (this is a pattern also used by many Swagger tools, the difference here is that OSDB produces the console from RDF-based Linked Data i.e., leverage relationship type semantics that it understands by way of term definitions from the RDF and Schema.org vocabularies).
Here’s the console with input which in this case takes the form of SPARQL Query text.
Result of hitting the “Execute Action” button which leads to the content of a Query Results document being presented in your browser.
Using our Structured Data Sniffer’s SPARQL Editor feature, you can jump straight in to Query view and/or modification mode, if you choose.
By changing the &query
parameter name to &qtxt
— in the HTTP URI/URL presented in your browser — you can also retrieve the content of DBpedia’s SPARQL Query editor which also enables you to view and/or modify query text.
REST-ful Interaction using Swagger Console
REST-ful Interaction using curl
You can repeat the human-centric interactions covered so far by using curl
to emulate the behavior of an HTTP User agent. Basically, the state of your application experience is guided by the document content retrieved; i.e., you can work your way through various OSDB actions, courtesy of its registered Web Services API and their associated actions (operations).
Examples:
Given an OSDB registered API (Web Service) labeled dbpedia_query_api, here’s how you use curl
to obtain its associated Actions:
Command
curl -ik "https://osdb.openlinksw.com/osdb/api/v1/services/dbpedia_query_api"
Result
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH
Content-Type: application/json; charset=utf-8
Content-Length: 481
ETag: W/"1e1-XyFwqo7LTFhDsxTF3Ot9Hw"
Date: Wed, 24 Jan 2018 16:25:08 GMT
Connection: keep-alive{"status":"success","method":"describe_service","api":"/osdb/api/v1/services/:service_id","response":{"service_id":"dbpedia_query_api","service_name":"dbpedia_query_api","description":"Virtuoso is a modern enterprise grade solution for data access, integration, and relational database management (SQL Tables and/or RDF based Property/Predicate Graphs).\n","import_source_uri":"http://linkeddata.uriburner.com/about/id/entity/https/api.swaggerhub.com/apis/DBpedia/Virtuoso/1.0.0"}}
Given OSDB Action labeled find_related_dbpedia_resources_for_a_given_string, here’s how its call invocation structure (or call signature) is obtained:
Command
curl -ik "https://osdb.openlinksw.com/osdb/api/v1/actions/dbpedia_query_api/find_related_dbpedia_resources_for_a_given_string"
Response
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH
Content-Type: application/json; charset=utf-8
Content-Length: 1025
ETag: W/"401-eIU1xysLbL3MFnOkQeET3w"
Date: Wed, 24 Jan 2018 16:26:54 GMT
Connection: keep-alive{"status":"success","method":"describe_action","api":"/osdb/api/v1/actions/:service_id/:action_id","response":{"action_id":"find_related_dbpedia_resources_for_a_given_string","description":"Find related DBpedia resources for a given string","entry_point":{"http_method":"GET","url_template":null,"url":"http://dbpedia.org//sparql","name":null,"description":null,"encoding_types":["application/json","application/xml"],"content_types":["application/javascript","application/json","application/rdf+xml","application/sparql-results+json","application/sparql-results+xml","application/vnd.ms-excel","text/csv","text/cxml","text/html","text/plain","text/tab-separated-values","text/turtle","text/x-html+tr"],"parameters":[{"parameter_name":"query","display_name":"query","description":"Query Text","type":"query","required":1,"permitted_values":null},{"parameter_name":"default-graph-uri","display_name":"default-graph-uri","description":"Default Data Set Name (Graph IRI)","type":"query","required":0,"permitted_values":null}]}}}
You can invoke the Action labeled find_related_dbpedia_resources_for_a_given_string with a preference to return a document URI/URL rather than content:
Command
curl -ki -X POST -d '{ "query":"SELECT DISTINCT ?o WHERE {?s a ?o} limit 50", "default-graph-uri": "http://dbpedia.org", "osdb:output_type": "url_only" }' -H 'Content-Type: application/json' "https://osdb.openlinksw.com/osdb/api/v1/actions/dbpedia_query_api/find_related_dbpedia_resources_for_a_given_string/exec"
Response
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH
Content-Type: text/plain; charset=utf-8
Content-Length: 145
ETag: W/"91-2Bp1lwijcfj85b+a4LRIhA"
Date: Wed, 24 Jan 2018 16:30:09 GMT
Connection: keep-alivehttp://dbpedia.org//sparql?query=SELECT%20DISTINCT%20%3Fo%20WHERE%20%7B%3Fs%20a%20%3Fo%7D%20limit%2050&default-graph-uri=http%3A%2F%2Fdbpedia.org
You can invoke the Action labeled find_related_dbpedia_resources_for_a_given_string with a preference to return HTML content:
Command
curl -ki -X POST -d '{ "query":"SELECT DISTINCT ?o WHERE {?s a ?o} limit 50", "default-graph-uri": "http://dbpedia.org", "osdb:response_format": "text/html" }' -H 'Content-Type: application/json' "https://osdb.openlinksw.com/osdb/api/v1/actions/dbpedia_query_api/find_related_dbpedia_resources_for_a_given_string/exec"
You can invoke the Action labeled find_related_dbpedia_resources_for_a_given_string with a preference to return RDF-Turtle content:
Command
curl -ki -X POST -d '{ "query":"SELECT DISTINCT ?o WHERE {?s a ?o} limit 50", "default-graph-uri": "http://dbpedia.org", "osdb:response_format": "text/turtle" }' -H 'Content-Type: application/json' "https://osdb.openlinksw.com/osdb/api/v1/actions/dbpedia_query_api/find_related_dbpedia_resources_for_a_given_string/exec"
Bearing in mind that OSDB is an aggregator of APIs (documented using Swagger or described from onset using RDF Language), with each API registered it gains N number of Action Invocation capabilities (or skills).
Here’s an example using curl
to explore Uber Product Offers, via OSDB:
Command
curl -ikL -X POST -d '{ "latitude":"37.7759792", "longitude":"-122.41823", "osdb:output_type":"generate_rdf", "osdb:response_format":"application/ld+json" }' -H 'Content-Type: application/json' "https://osdb.openlinksw.com/osdb/api/v1/actions/uber/products/exec"
Response
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, PATCH
Content-Type: application/ld+json; charset=utf-8
Content-Length: 34630
ETag: W/"8746-zUo255Oi5/zBJE2THpB1kA"
Date: Wed, 24 Jan 2018 16:36:05 GMT
Connection: keep-alive{ "@graph": [
{ "@id": "http://schema.org/",
"@type": "http://www.openlinksw.com/schema/attribution#DataSource",
"http://www.openlinksw.com/schema/attribution#hasNamespacePrefix": "schema" },
{ "@id": "https://sandbox-api.uber.com/v1/products?latitude=37.7759792&longitude=-122.41823",
…
Conclusion
I’ve used OSDB’s functionality to demonstrate the fact that the notion of a Semantic Web of Linked Data and REST-ful interactions using APIs aren’t mutually exclusive in any way. In fact, they are symbiotic aspects of what makes the Web’s underlying architecture so powerful.
A single instance of OSDB provides a REST-ful interaction point for engaging a variety of Actions extracted from a variety of APIs documented using Swagger and/or RDF documents.
Fundamentally, the architecture that delivered the Web is also a vehicle for loosely-coupled exploitation of the time-tested M-V-C pattern, along the following lines:
- Model — Semantic Web of Linked Data
- Viewer — HTML-based Web of Documents
- Controller — REST-ful interaction with APIs, where operations are part of a Web of Actions
Links
- Open Smart Data Bot — a Smart Agent that dynamically generates action (operation) interaction interfaces (for both humans and machines) via webby data (a/k/a Linked Data) derived from APIs documented using Swagger (specifically, JSON Content-Type)
- Terms from the RDF and Schema.org vocabularies
- URIBurner Service — a live instance of Virtuoso that has the Linked Data module (a/k/a “Sponger”) module enabled
- OpenLink Data Explorer (ODE) browser extension — adds Linked Data transformation services to existing Web Browsers
- OpenLink Structured Data Sniffer (OSDS) — discovers Structured Metadata embedded in HTML documents
- DBpedia — kernel that spawned the massive Linked Open Data Cloud enclave within the World Wide Web
- A DBpedia Query API — documented using Swagger and published via Swagger Hub
- APIs & REST — by Roy Fielding
- Linked Data Principles — by Tim Berners-Lee
Related
- Swagger API Documentation Standard
- API Descriptions for both Humans & Machines
- Describing New York Times Web Service
- Describing a Faceted Browsing oriented Search Service
- RDF Vocabulary — the foundation of RDF to which all RDF-aware tools subscribe
- What is the Semantic Web Answer on Quora
- Virtuoso Home Page — About Virtuoso
- Universal Data Access Drivers Page — About our ODBC, JDBC, ADO.NET, and OLE-DB providers
- OpenLink Software Home Page — About OpenLink Software