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.hasIssues()){
// 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();Compass comes with example-driven documentation that explains common FAIR Signposting validation scenarios step by step:
-
FAIR Signposting Level 1 validation:
doc/level1-basic-validation.md -
FAIR Signposting Level 2 discovery using Link Sets (RFC 9264):
doc/level2-discovery.md -
Handling multiple Link Sets with different aggregation strategies
-
Validation of incomplete or non-compliant Signposting data
Each document is self-contained and focuses on a single concept, using real-world HTTP Link header examples and minimal Java snippets.
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?”
To continuously assess Compass’ validator behavior on real-world FAIR Signposting examples, we maintain an offline, apple-to-apple benchmark runner based on the A2A FAIR Signposting HTTP scenarios.
The runner replays harvested HTTP header fixtures (primarily RFC 8288 Link headers), converts them into the WebLink model, and validates them with Compass against scenario-specific expectations (relations and expected issues). This makes it easy to reproduce behavior across versions and detect regressions.
Scope note: The benchmark currently covers HTTP scenarios only. Inline HTML signposting is intentionally not included yet (that would mainly benchmark HTML parsing, not Compass’ WebLink validation). Network-based behavior (dereferencing, conneg, remote Link Set fetching) is also out of scope.
Benchmark runner repository: https://github.com/qbicsoftware/compass-a2a-runner
Compass is an open-source research software project and welcomes contributions from the community.
You can contribute by:
- reporting bugs or unexpected behavior,
- improving documentation or examples,
- proposing new validation rules or features,
- submitting code improvements or fixes.
Please read the Contribution Guidelines before opening an issue or pull request.
All contributions are reviewed, and design discussions are encouraged — especially for changes affecting validation semantics or public APIs.
Compass implements the community standards behind FAIR Signposting and Web Linking.
- FAIR Signposting specification: https://signposting.org/FAIR/
- RFC 8288 — Web Linking: https://datatracker.ietf.org/doc/html/rfc8288
- RFC 9264 — Linkset: https://www.rfc-editor.org/rfc/rfc9264.html
We thank the authors and contributors of these specifications for their work. Compass is an independent implementation and is not affiliated with or endorsed by the specification authors.