RDF/OWL content-negotiation using NGINX
published: (updated: )
by Harshvardhan J. Pandit
is part of: Semantic Web
content-negotiation semantic-web web-dev
A similar particulars for Apache are available from W3C Best practices for publishing RDF Vocabularies
What is content-negotiation?
Wikipedia defines content-negotiation as different (mime types) documents are served at the same URI. In simpler terms, this allows requesting different formats on the same URI. Hence the negotiation of content, as in, the requester asks for a specific content and the server sends it, or replies back with what is available. This allows a single URI for the resource, where the requester can get the data in whatever format they want, provided the server already has that format. So a request for an image at http://example.com/image will image.jpeg if the requester wants a JPEG, or it may send image.png as default.
Content negotiation for RDF and OWL
For serving ontologies and datasets, content negotiation is a valuable mechanism because of the varying formats, while ontologies need to be served with a single, unchanging url.
Therefore, say, when an ontology or dataset is served at http://example.com/ontology, the requester can ask for RDF/XML
or Turtle
or N3
, and the server will respond correctly if the file exists on the server.
This also puts the onus on the maintainer of the ontology to keep a lot of versions of the ontology to fulfil content negotiation.
Setting up content negotiation on Nginx
Nginx is a simple, versatile web server, which is great for quick handling of web apps, but the content-negotiation aspect is not as fleshed out as with Apache. Therefore, the following will only enable content-negotiation partially and has several holes in it. But it gets the job done.
First, set the following snippet in the http
section of /etc/nginx/nginx.conf
to map the request type to file types.
map $http_accept $ld_suffix{
"~*owl" ".owl";
"~*rdf" ".rdf";
"~*xml" ".xml";
}
Then, to make Nginx aware of mime types we want to serve, add the following in /etc/nginx/mime.types
to the existing types
dictionary.
text/turtle ttl;
application/rdf+xml rdf;
application/n-triples nt;
application/ld+json jsonld;
application/owl+xml owl;
text/trig trig;
application/n-quads nq;
Once this is done, open the webapp configuration (usually in sites-*
) and set it up so-
location /ontologies {
alias /apps/ontologies;
autoindex on;
try_files $uri $uri$ld_suffix =404;
}
which will serve the files out of /apps/ontologies/
by basically trying out different combinations of files, and if not available, will sent a HTTP-404
.
An easy way to test this is using curl
as -
curl -I -L -H "Accept: <MIME-TYPE>" URI
# response should contain
# Content-Type: <MIME-TYPE>