This repository is in an early and experimental stage.
- APIs may change or be removed without prior notice
- Documentation may be incomplete or outdated
- Backward compatibility is not guaranteed
Use at your own risk, but provide feedback and suggestions in an issue or contribution in form of a pull-request.
<!-- You might want to check for the latest version -->
<groupId>life.qbic</groupId>
<artifactId>compass</artifactId>
<version>1.0.0</version>Check the latest component version on Maven Central.
curl -I https://zenodo.org/records/17179862A simple HTTP GET request to the Zenodo record will result in the following HTTP header:
Full HTTP Link header returned by Zenodo (real-world example)
HTTP/1.1 200 OK
server: nginx
date: Mon, 01 Dec 2025 12:14:33 GMT
content-type: text/html; charset=utf-8
content-length: 85404
vary: Accept-Encoding
link: <https://orcid.org/0009-0006-0929-9338> ; rel="author" , <https://ror.org/00v34f693> ; rel="author" , <https://ror.org/03a1kwz48> ; rel="author" , <https://doi.org/10.5281/zenodo.17179862> ; rel="cite-as" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/dcat+xml" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/json" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/ld+json" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/ld+json;profile="https://datapackage.org/profiles/2.0/datapackage.json"" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/marcxml+xml" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/vnd.citationstyles.csl+json" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/vnd.datacite.datacite+json" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/vnd.datacite.datacite+xml" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/vnd.geo+json" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/vnd.inveniordm.v1+json" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/vnd.inveniordm.v1.full+csv" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/vnd.inveniordm.v1.simple+csv" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/x-bibtex" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/x-dc+xml" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="text/x-bibliography" , <https://zenodo.org/records/17179862/files/22-09-2025_13-National-Biobanken-Symposium_FAIR-IN-Biobanking_SG.pdf> ; rel="item" ; type="application/pdf" , <https://zenodo.org/records/17179862/files/22-09-2025_13-National-Biobanken-Symposium_FAIR-IN-Biobanking_SG.odp> ; rel="item" ; type="application/octet-stream" , <https://zenodo.org/records/17179862/files/22-09-2025_13-National-Biobanken-Symposium_FAIR-IN-Biobanking_SG.pptx> ; rel="item" ; type="application/octet-stream" , <https://creativecommons.org/licenses/by/4.0/legalcode> ; rel="license" , <https://schema.org/PresentationDigitalDocument> ; rel="type" , <https://schema.org/AboutPage> ; rel="type" , <https://zenodo.org/api/records/17179862> ; rel="linkset" ; type="application/linkset+json"For the sake of simplicity and to show the FAIR signposting use case Level 1, we use only some of the link targets:
- the author
- the citation
- the record API endpoint for additional meta-data
import life.qbic.compass.SignPostingProcessor;
import life.qbic.compass.model.SignPostingView;
import life.qbic.linksmith.core.WebLinkProcessor;
import life.qbic.linksmith.spi.WebLinkValidator.ValidationResult;
// Raw header of an HTTP response with link attribute
// 'link: <https://orcid.org/0009-0006-0929-9338> ; rel="author" , <https://ror.org/00v34f693> ; rel="author"'
String rawHeader =
'<https://orcid.org/0009-0006-0929-9338> ; rel="author" , <https://doi.org/10.5281/zenodo.17179862> ; rel="cite-as" , <https://zenodo.org/api/records/17179862> ; rel="describedby" ; type="application/json"';
WebLinkProcessor webLinkProcessor = new WebLinkProcessor.Builder().build();
ValidationResult result = webLinkProcessor.process(rawHeader);
// Investigate the validation result
// ...
// Fetch the weblinks and let compass process them
// Default builds to FAIR Signposting Level 1 validation
SignPostingProcessor processor = new SignPostingProcessor.Builder().build();
SignPostingResult signPostResult = processor.process(result.weblinks());
if(signPostResult.containsIssues()){
// Retrieve the report
var report = result.report();
// Investigate the report
// ...
return;
}
SignPostingView view = signPostResult.signPostingView();
// Access to cite-as typed WebLinks
List<WebLink> citeAs = view.citeAs();
// Access to describedby typed WebLinks
List<WebLink> metadata = view.describedBy();
// Access to author typed WebLinks
List<WebLink> authors = view.author();Additional, self-contained examples are available in the examples/ directory, including:
- FAIR Signposting Level 1 validation scenarios
- Level 2 discovery using Link Sets (RFC 9264)
- Handling multiple Link Sets with different aggregation strategies
- Validation of incomplete or non-compliant Signposting data
Each example is designed to be minimal, runnable, and focused on a single concept.
Compass is a lightweight Java library for validating and interpreting FAIR Signposting. It builds on Linksmith and adds:
- defensive RFC 8288 model-level validation,
- FAIR Signposting Level 1 and Level 2 recipe validation,
- semantic views and Link Set (RFC 9264) processing.
Compass operates entirely in memory, performs no network requests,
and works with WebLink objects regardless of how they were created.
| Without Compass | With Compass |
|---|---|
| Assume WebLinks are well-formed | Defensive validation of RFC 8288 model invariants |
| Validation tied to parsing strategy | Validation independent of how WebLinks were created |
Manual inspection of rel values and parameters |
Semantic views for Landing Pages, Metadata Resources, and Content Resources |
| No clear distinction between Level 1 and Level 2 Signposting | Explicit validators for Level 1 and Level 2 recipes |
| Link Sets parsed and interpreted ad-hoc | Ready-to-use parsers for RFC 9264 Link Set formats |
| Ambiguous handling of multiple Link Sets | Pluggable aggregation strategies with defined semantics |
| Validation logic scattered across client code | Centralized, reusable Signposting validation pipeline |
Compass is designed to complement — not replace — Linksmith:
-
Linksmith
- Parses Web Linking syntax
- Validates RFC 8288 during parsing
- Produces
WebLinkmodel objects
-
Compass
- Does not assume how
WebLinks were produced - Validates RFC 8288 model-level constraints defensively
- Applies FAIR Signposting semantics and recipes
- Interprets Level 2 Link Sets (RFC 9264)
- Does not assume how
Together, they form a clean separation of concerns:
- Linksmith: “Is this syntactically valid Web Linking?”
- Compass: “Is this WebLink model sound, and what does it mean for FAIR Signposting?”