Nancy serializers for RDF media types
Nancy.Rdf is a set of Nancy components, which allow working with POCO models as usual and serving them as RDF media types:
- JSON-LD
- RDF/XML
- Turtle
- Notation3
- n-triples
Under the hood dotNetRDF is used. Thus in the future I plan to add the possibility to serve dotNetRDF graphs and datasets directly.
PM> Install-Package Nancy.Rdf
You may also want to install Rdf.Vocabularies, so that you don't have to remember all of those common URIs.
PM> Install-Package Rdf.Vocabularies
With Nancy.Rdf I struggle to follow the Super-Duper-Happy-Path. Nancy has an unparalelled extensibility model and thanks to SDHP there is a minimal number of steps required to get RDF up and running in your API. It just works!
You can try out the code below by running the sample project
This is done with JsonLD.Entites. A simples possible model is an ordinary .NET type with a Context
and Type
properties which are mapped to JSON-LD's @context
and @type
keys respectively:
using JsonLD.Entities.Context;
using Newtonsoft.Json;
using Vocab;
public class Person
{
public string Id { get; set; }
[JsonProperty("givenName")]
public string Name { get; set; }
public string LastName { get ;set; }
public DateTime DateOfBirth { get; set; }
[JsonProperty]
private string Type
{
get
{
return Foaf.Person;
}
}
private static JObject Context
{
get
{
return new JObject(
"givenName".IsProperty(Foaf.givenName),
"lastName".IsProperty(Foaf.lastName),
"dateOfBirth".IsProperty(Schema.birthDate)
);
}
}
}
The Context
property defines how model properties map to RDF terms. By default properties are serialized in camelCase, but the
standard Newtonsoft.Json [JsonProperty]
can be used to overwrite that. Id
is seriaized as @id
; Type
is serialized as @type
.
For more information on serialization see JsonLD.Entities documentation/samples.
public class PersonModule : NancyModule
{
public PersonModule()
{
Get["person/{id}"] = _ => {
return new Person {
Id = "http://api.guru/person/" + _.id,
Name = "John",
LastName = "Doe",
DateOfBirth = new DateTime(1967, 8, 2)
};
};
}
}
curl http://my.host/person/2 -H Accept:application/ld+json
will return JSON-LD
{
"@context": {
"givenName": "http://xmlns.com/foaf/0.1/givenName",
"lastName": "http://xmlns.com/foaf/0.1/lastName",
"dateOfBirth": "http://schema.org/birthDate"
},
"@id": "http://api.guru/person/2",
"@type": "http://xmlns.com/foaf/0.1/Person",
"givenName": "John",
"lastName": "Doe",
"dateOfBirth": "1967-08-02T00:00:00"
}
Other RDF media types are served by serializing to JSON-LD first and then converting to their respective graph format.
The JSON-LD context can become quite lengthy and Nancy.Rdf makes it trivialy to serve remote contexts and replace the @context
object on serialized models. By implementing IContextPathMapper
it is possible to make Nancy.Rdf replace context of serialized
models and have it served from a dedicated module. For convenience there is a base class to set that up.
public class ContextPathMapper : Contexts.DefaultContextPathMapper
{
public ContextPathMapper()
{
ServeContextOf<Person>();
}
}
The above class will expose a /_contexts/Person
resource and use it as context whenever an instance of Person
is serialized.
The _contexts
part can be changed by overriding the BasePath
property. The /Person
part can be changed by passing a parameter
to the ServeContextOf
method call.
Great thanks to the Nancy team for creating this great framework. Thanks to the NuGet team for implementing the JSON-LD API.
The icon desiged by Piotrek Chuchla from The Noun Project