R4R#

R4R derives its API from a directory tree and passes results through Apache Velocity templates the developer writes. It binds a single endpoint for the whole server, so it answers from OpenCitations Meta only, and labels every response application/json.

from helper import call

A simple request#

Looking up a DOI returns the article’s OMID and title from OpenCitations Meta.

call("http://localhost:8083/articles?doi=10.1007/s11192-022-04367-w")
curl 'http://localhost:8083/articles?doi=10.1007/s11192-022-04367-w' 

# 200 

[
  {
    "omid": "https://w3id.org/oc/meta/br/061202127149",
    "title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data"
  }
]

The join#

No join. A single endpoint is bound for the whole server, so R4R cannot reach OpenCitations Index to add the reference count.

Output#

Whatever the template writes.

call("http://localhost:8083/articles/061202127149")
curl http://localhost:8083/articles/061202127149 

# 200 

{
  "omid": "https://w3id.org/oc/meta/br/061202127149",
  "title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data",
  "publicationDate": "2022-06"
}

Pagination#

size and offset page the result, where offset is a page index; no Link headers and no total. The agents are a nested resource (a subfolder).

call("http://localhost:8083/articles/061202127149/agents?size=2&offset=1")
curl 'http://localhost:8083/articles/061202127149/agents?size=2&offset=1' 

# 200 

[
  {
    "agent": "https://w3id.org/oc/meta/ra/06220110984",
    "name": "Nooshin Shahidzadeh"
  },
  {
    "agent": "https://w3id.org/oc/meta/ra/061206532420",
    "name": "Sara Coppini"
  }
]

Versioning#

Not supported.

API description#

Not supported: /doc serves only static files placed there by hand.

Consumer authentication#

Global: API_USERS guards every operation, not only writes. The r4r-auth service (port 8084) is the same image with API_USERS=demo:demo. Without credentials the request is rejected with 401.

call("http://localhost:8084/articles/061202127149")
curl http://localhost:8084/articles/061202127149 

# 401 

{
  "timestamp": 1789660532515,
  "status": 401,
  "error": "Unauthorized",
  "message": "Full authentication is required to access this resource",
  "path": "/articles/061202127149"
}

With the credentials the same request succeeds.

call("http://localhost:8084/articles/061202127149", basic_auth=("demo", "demo"))
curl -u demo:demo http://localhost:8084/articles/061202127149 

# 200 

{
  "omid": "https://w3id.org/oc/meta/br/061202127149",
  "title": "Identifying And Correcting Invalid Citations Due To DOI Errors In Crossref Data",
  "publicationDate": "2022-06"
}

Endpoint authentication#

Not supported.

Operations#

GET only. The other methods are rejected.

call("http://localhost:8083/articles/061202127149", method="POST", max_lines=0)
call("http://localhost:8083/articles/061202127149", method="PUT", max_lines=0)
call("http://localhost:8083/articles/061202127149", method="DELETE", max_lines=0)
curl -X POST http://localhost:8083/articles/061202127149 

# 403 


... (7 more lines)
curl -X PUT http://localhost:8083/articles/061202127149 

# 403 


... (7 more lines)
curl -X DELETE http://localhost:8083/articles/061202127149 

# 403 


... (7 more lines)

Caching#

Not supported. The tool reaches OpenCitations Meta through a proxy that records every request it forwards, and two identical calls send the same SPARQL requests twice.

from helper import count_endpoint_requests

count_endpoint_requests("http://localhost:8083/articles?doi=10.1007/s11192-022-04367-w")
First call: 200 , SPARQL requests that reached the endpoint: 1
Second call: 200 , SPARQL requests that reached the endpoint: 1