Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/validate_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


def get_pushed_files():
return [f"./{file}" for file in changed_files if file.endswith(".json")]
return [f"./{file}" for file in changed_files if ( file.endswith(".json") and not file.endswith("skg-if-api.json") ) ]


def validate_file(file_path):
Expand Down
149 changes: 141 additions & 8 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,154 @@ nav_order: 7
# API Specifications

{: .highlight }
**Work in progress**: The WG agreed with RDA a 6-month deadline extension (i.e., end of June 2025) in order to deliver full-fledged API specifications that go beyond the "vanilla" resolvers describe in the first iteration of the SKG-IF. We opted for **OpenAPI** to describe the endpoints and the format of the objects to exchange on the wire; the *ALPHA* specifications are shared below. For the sake of completeness, you can check our working document on API development [here](https://docs.google.com/document/d/1t7b7h28UTtM56Sda4NGJIp0hnQfGbcVVGn12fny9wfI/edit?tab=t.0#heading=h.hso3muyqtlhx).

## Versions

The current (i.e., last) version of the SKG-IF OpenAPI specifications is available at [https://w3id.org/skg-if/api/skg-if-openapi.yaml](https://w3id.org/skg-if/api/skg-if-openapi.yaml).
**OpenAPI** is used to describe the endpoints and the format of the objects to exchange on the wire, the specifications are shared below.
For the sake of completeness, you can also check the [SKG-IF OpenAPI Implementer documentation](https://docs.google.com/document/d/1t7b7h28UTtM56Sda4NGJIp0hnQfGbcVVGn12fny9wfI/edit?tab=t.0#heading=h.hso3muyqtlhx).

One can access the OpenAPI specifications of all (current and previous) versions by using a version number in the `w3id.org` URL, before the name of the YAML file, following this pattern:
* The current (i.e., last) version of the SKG-IF OpenAPI specifications is available at [https://w3id.org/skg-if/api/skg-if-openapi.yaml](https://w3id.org/skg-if/api/skg-if-openapi.yaml).
* One can access the OpenAPI specifications of all (current and previous) versions by using a version number in the `w3id.org` URL, following this pattern:
`https://w3id.org/skg-if/api/<X.Y.Z>/skg-if-openapi.yaml`. For instance: `https://w3id.org/skg-if/api/1.0.0/skg-if-openapi.yaml` allows to access to version 1.0.0 of the SKG-IF OpenAPI specifications.


The SKG-IF OpenAPI version, present in the YAML, is independent from the SKG-IF Data model version.

``` yaml
openapi: 3.1.0
info:
version: 1.0.0
title: SKG-IF OpenAPI - compatible with SKG-IF Data Model 1.1.0

...
"@context":
"https://w3id.org/skg-if/context/1.1.0/skg-if.json", // Fixed SKG-IF data model context
"https://w3id.org/skg-if/context/1.0.0/skg-if-api.json", // Fixed SKG-IF API context
{
"@base": "https://w3id.org/skg-if/sandbox/acme/"
}
...

```

## Viewers

You can also visualize the OpenAPI specifications with standard tools like :

* Stoplight : [https://elements-demo.stoplight.io/?spec=https://w3id.org/skg-if/api/skg-if-openapi.yaml](https://elements-demo.stoplight.io/?spec=https://w3id.org/skg-if/api/skg-if-openapi.yaml)
* Swagger : [https://editor.swagger.io/?url=https://w3id.org/skg-if/api/skg-if-openapi.yaml](https://editor.swagger.io/?url=https://w3id.org/skg-if/api/skg-if-openapi.yaml)


## Define your @base

`@base` is a default prefix domain fallback for all identifiers not defined as URLs in the `@graph`
A `local_identifier` value, when not starting with “http”, is interpreted by concatenation to the `@base`.

For the `local_identifier` domain (your `@base`), you have a few options for the ACME organisation.

* Use `https://w3id.org/skg-if/sandbox/acme/` . We don’t recommend it for prod because it does not resolve anywhere ( related to the ACME organisation )
* Define a [w3id.org](https://w3id.org) domain ex: `https://w3id.org/acme/` . You can set up w3id.org to redirect to your catalogue. ex: `https://w3id.org/acme/prod-1` => `https://www.acme.com/product-catalogue/prod-1`
* Use a graph dedicated domain you already have ex: `https://www.acme.com/theskg/`, `https://www.acme.com/theprodgraph/`

Make sure that you generate distinct URLs ids for person, product... They should not conflict.

## Endpoints and JSON-LD output

* The SKG-IF OpenAPI defines 2 types of endpoints
* Get _Entity_ by Id
* Get List of _Entity_
* The SKG-IF OpenAPI endpoints outputs are JSON-LD and compatible with the [SKG-IF data model](https://skg-if.github.io/interoperability-framework/)

## API links

* The `@graph` array contains entities, identified by their `local_identifier`, each entity may have relation to other entities also identified by their `local_identifier`.
* From a client perspective, if the sub entity is not embedded with its fields, you may need to perform sub queries to access these fields.
* The JSON-LD output contains a `meta` section SHOULD provide you API links for each entity, identified by its `local_identifier`. As a client you are not supposed to guess the API URL from the `local_identifier` format, there is no standard for the API domain prefix, each implementer is free to have a domain for its `local_identifier` and another one for its API (It is even recommended).


Get Product by Id : `https://acme.com/skg-if/api/products/prod-1`

``` json
{
"meta" : {
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/prod-1", // parent local_identifier / PID
"entity_type": "single_entity",
"api_items": [
{
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/pers-1", // local_identifier / PID
"urls": [
{
"entity_type": "link",
"rel": "self",
"href": "https://acme.com/skg-if/api/persons/pers-1" // API link
}
]
}
]
},
"@graph": [
{
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/prod-1",
"contributions": [
{
"by" : {
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/pers-1"
//...
}
//...
}
]
//...
}
]
}
```
https://w3id.org/skg-if/api/<X.Y.Z>/skg-if-openapi.yaml

Get List of Product : `https://acme.com/skg-if/api/products?filter=xxx&page=1`

``` json
{
"meta": {
"local_identifier": "https://acme.com/skg-if/api/products?filter=xxx&page=1", // search identifier, API link
"entity_type": "single_entity",
"api_items": [
{
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/pers-1", // local_identifier / PID
"urls": [
{
"entity_type": "link",
"rel": "self",
"href": "https://acme.com/skg-if/api/persons/pers-1" // API link
}
]
}
]

},
"@graph": [
{
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/prod-1",
"contributions": [
{
"by" : {
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/pers-1"
//...
}
//...
}
]
//...
},
{
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/prod-1"
//...
},

]
}

```

For instance:
* `https://w3id.org/skg-if/api/1.0.0/skg-if-openapi.yaml` allows to access to version 1.0.0 of the OpenAPI specifications;
* `https://w3id.org/skg-if/api/0.2.0/skg-if-openapi.yaml` allows to access to version 0.2.0 of the OpenAPI specifications;
* and so on.



23 changes: 22 additions & 1 deletion openapi/ver/1.0.0/context/skg-if-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"search_result": {
"@id": "as:Collection"
},
"single_entity": {
"@id": "as:Object"
},
"part_of": {
"@id": "as:partOf"
},
Expand All @@ -27,6 +30,24 @@
"prev_page": {
"@id": "as:prev"
},
"meta": "@nest"
"meta": "@nest",
"api_items": {
"@id": "as:items",
"@container": "@set"
},
"urls": {
"@id": "as:url",
"@container": "@set"
},
"rel": {
"@id": "as:rel"
},
"href": {
"@id": "as:href",
"@type": "@id"
},
"media_type":{
"@id": "as:mediaType"
}
}
}
23 changes: 22 additions & 1 deletion openapi/ver/current/context/skg-if-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"search_result": {
"@id": "as:Collection"
},
"single_entity": {
"@id": "as:Object"
},
"part_of": {
"@id": "as:partOf"
},
Expand All @@ -27,6 +30,24 @@
"prev_page": {
"@id": "as:prev"
},
"meta": "@nest"
"meta": "@nest",
"api_items": {
"@id": "as:items",
"@container": "@set"
},
"urls": {
"@id": "as:url",
"@container": "@set"
},
"rel": {
"@id": "as:rel"
},
"href": {
"@id": "as:href",
"@type": "@id"
},
"media_type":{
"@id": "as:mediaType"
}
}
}
12 changes: 6 additions & 6 deletions openapi/ver/current/sample_data/grants/grant_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"https://w3id.org/skg-if/context/1.1.0/skg-if.json",
"https://w3id.org/skg-if/context/1.0.0/skg-if-api.json",
{
"@base": "https://w3id.org/skg-if/sandbox/my-skg-acronym/"
"@base": "https://w3id.org/skg-if/sandbox/acme/"
}
],
"@graph": [
{
"local_identifier": "http://example.com/skg-if/api/grants/6f368a3a-b1cf-498f-b2de-27135d1e0011",
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/grant-1",
"identifiers": [
{
"scheme": "doi",
Expand All @@ -25,7 +25,7 @@
},
"acronym": "GraspOS",
"funding_agency": {
"local_identifier": "http://example.com/skg-if/api/organisations/org-xxx",
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/org-1",
"entity_type": "organisation",
"identifiers": [
{
Expand All @@ -48,7 +48,7 @@
"website": "https://graspos.eu",
"beneficiaries": [
{
"local_identifier": "http://example.com/skg-if/api/organisations/xxx",
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/org-1",
"entity_type": "organisation",
"identifiers": [
{
Expand All @@ -65,7 +65,7 @@
"contributions": [
{
"by": {
"local_identifier": "http://example.com/skg-if/api/persons/xxx",
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/pers-1",
"entity_type": "person",
"identifiers": [
{
Expand All @@ -79,7 +79,7 @@
},
"declared_affiliations": [
{
"local_identifier": "http://example.com/skg-if/api/organisations/xxx",
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/org-1",
"entity_type": "organisation",
"identifiers": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"https://w3id.org/skg-if/context/1.1.0/skg-if.json",
"https://w3id.org/skg-if/context/1.0.0/skg-if-api.json",
{
"@base": "https://w3id.org/skg-if/sandbox/my-skg-acronym/"
"@base": "https://w3id.org/skg-if/sandbox/acme/"
}
],
"@graph": [
{
"local_identifier": "http://example.com/skg-if/api/organisations/6f368a3a-b1cf-498f-b2de-222222222",
"local_identifier": "https://w3id.org/skg-if/sandbox/acme/org-1",
"entity_type": "organisation",
"identifiers": [
{
Expand Down
Loading
Loading