EOSC Node DCAT Service Catalogue Implementation Guide
Following on from the #EOSC hackathon I ran a few weeks ago, I thought I would write a brief implementation guide for any other nodes that want to try playing with what we did
Following on from an earlier post around the hackathon I ran, where we took a couple of EOSC node service catalogues and federated them together, I have been repeatedly asked if I’d go into a little more detail as to what we did. My hope is that other nodes might want to start playing with this too, and letting me know where some of the gaps are, and hopefully this might result in a bit of a bottom up federation starting to form!
The Scope
In the hackathon we took the existing EOSC EU Node (EEN) service catalogue format, which some nodes already expose and mapped it over DCAT + JSON-LD using a schema mapping I put together below.
The choice of DCAT came out of the semantic interoperability work, and is well understood and extensible. The EOSC node service catalogue format, which was an output from EOSC Future, is a little bit more custom and less extensible in its current form. With that in mind I only mapped the minimal set of required fields associated with service discovery, and such mappings should not be considered canonical – this is very much a proof of concept.
Metadata for more advanced functionality (search, order provisioning, etc) is considered out of scope, at least for now.
Mapping EEN to DCAT
Our respective nodes in the hackathon already exposed their services via a public endpoint in EEN format (well, the Life Sciences Connect node, actually exposed it in ARIA format, but I had already done some work to map that to EEN via my micro service), so the next step was to map this across to DCAT.
This is the mapping table I came up with:
| EEN field | Required | DCAT-compatible mapping | Notes |
| serviceBundle.id / service.id | Yes | dcterms:identifier and resource URI | Use as stable ID. If not URI, mint one. |
| name | Yes | dcterms:title | Main display title. |
| webpage | Yes | dcat:landingPage | Human-facing service page. |
| description | Yes | dcterms:description | Main abstract. |
| scientificDomains[].scientificDomain | Yes | dcat:theme → skos:Concept | Use EEN scientific domain concept scheme. |
| categories[].category | Yes | dcterms:type or dcat:theme → skos:Concept | Suggesteddcterms:type for service type, optionally also dcat:theme. |
| targetUsers[] | Yes | dcterms:audience → skos:Concept | Not DCAT-native, but DC Terms is compatible. |
| languageAvailabilities[] | Yes | dcterms:language | Use ISO 639-1/BCP47 values, preferably lowercase like en, nl. |
| trl | Yes | eosc:technologyReadinessLevel → skos:Concept | Needs a small EOSC extension property. |
| orderType | Yes | eosc:orderType or dcterms:accessRights→ skos:Concept | open_access can also map to access rights. |
| accessModes[] | No | dcterms:accessRights→ skos:Concept | Good fit for free/conditional/restricted concepts. |
| alternativeIdentifiers[] | No | adms:identifier or repeated dcterms:identifier | Useadms:Identifier if you need type/value. |
| tagline | No | dcterms:abstract or schema:slogan | I’d useschema:slogan if using schema.org. |
| tags[] | No | dcat:keyword | Plain literals. |
| helpdeskEmail | No | dcat:contactPoint / vcard:hasEmail | Contact point object. |
| termsOfUse, privacyPolicy, accessPolicy | No | dcterms:rights, dcterms:accessRights, odrl:hasPolicy, or foaf:page | Depends how formal you want policies to be. |
In a case of comforting parallel evolution, another node produced a very similar mapping, so I was at least on the right track.
I made a fairly opinionated decision to use JSON-LD here, and as far as controlled vocabularies are concerned I was a little bit hand wavy. I also had to handle some data inconsistencies, for example, some fields being arrays even when only containing one item. Rather than argue who was right, I just handled things gracefully. Finally, I did not attempt to handle pagination in the first instance either, not that anybody has a lot of services right now.
For those of you who already expose an EEN feed, you might find my little micro service handy. Pull requests welcome!
Some additional plumbing…
One of the least specified aspect about all of these feeds, speaking as someone who came from the world of web standards and hacking on social networking applications, was that there was no plumbing around these that I could find. We had feeds, yes, but there was no apparent discovery mechanism.
I had poked around and there was something to do with “service capability discovery” that came out of the EOSC Beyond project. I have a sample below, and I would love to link you a specification, but I have literally only seen a JSON blob!
{
"node_endpoint": "https://pilot-node.instruct-eric.org/api/capabilities",
"capabilities": [
{
"capability_type": "Resource Catalogue",
"endpoint": "https://pilot-node.instruct-eric.org/catalogue/services",
"version": "1.0.0",
"api_spec": null,
"protocol": "REST",
"status": "OPERATIONAL"
},
{
"capability_type": "Monitoring",
"endpoint": "https://status.api.aria.services",
"version": "1.0.0",
"api_spec": null,
"protocol": null,
"status": null
},
{
"capability_type": "Helpdesk",
"endpoint": "https://instruct-helpdesk.scc.kit.edu",
"version": "1.0.0",
"api_spec": null,
"protocol": null,
"status": null
},
{
"capability_type": "AAI",
"endpoint": "https://auth.aria.services/auth/realms/ARIA",
"version": "1.0.0",
"api_spec": null,
"protocol": null,
"status": null
},
{
"capability_type": "Front Office",
"endpoint": "https://instruct-eric.org",
"version": "1.0.0",
"api_spec": null,
"protocol": null,
"status": null
}
]
}
A JSON blob on it’s own is no use, really, so I made an opinionated decision to stick it at .well-known/eosc-federation/node which worked quite well, although with my “internet” hat on I would also probably want to link to it from a <link> header or something – e.g <link rel="eosc-federation-node" href="...">.
I wrote a discovery library which finds these capabilities that you might find helpful, again pull requests welcome.
Conclusion
As I discussed in my hackathon debrief, this leaves a lot of things unaddressed – search, pagination, service identity and disambiguation, amongst others.
I should also stress that this is in no way “official”, it’s just me and some folks poking around and seeing what we can build. That being said, feel free to use what has been do here for your node as well, and let me have any feedback you may have!
Leave a Reply