CenterForDigitalHumanities / CenterForDigitalHumanities/rerum_server_nodejs

Profile Header + Response Properties

Open
#110 0 comments 0 reactions 0 assignees View on GitHub
equivalence
Dominant language
JavaScript
Stars
3
Forks
6
Avg merge
1h 25m
Merged PRs (30d)
3

Description

We need to support additional response properties for https://storedev.rerum.io /v1/api responses. These are properties that apps are expecting to exist in the responses that the up to date API no longer uses. Note that we only have to consider this for CRUD requests - all the GETters have the same returns between versions. To learn more about how to make our GETters support returns via different versions, see https://iiif.io/api/presentation/3.0/#63-responses (this is a separate thing).

**Introducing a Profile Header**
See https://profilenegotiation.github.io/I-D-Accept--Schema/I-D-accept-schema#rfc.section.4

To implement negotiation between a `https://storedev.rerum.io/api` v1.0 and v1.1 response, clients need a way to tell the API under which profile syntax they would prefer to see their resource in the response. Then, the API needs a way to respond to those clients whether or not it honored the preference and should note the profile used for the return. There is no clearly defined singular way to do this. Below are some roundtrip examples.

**Success Example 1**
A client POSTs a JSON document conforming to the JSON schema http://storedev.rerum.io/profile1.0 and thus ia expecting a response under that same schema. The server answers that it has provided the response under the requested schema
```HTTP
Request:
POST /v1/create HTTP/1.1
Content-Type: application/json
Profile: http://storedev.rerum.io/profile1.0
body {"hello":"world"}

Response:
HTTP/1.1 201 Created
Content-Type: application/json
Accept-Profile: http://storedev.rerum.io/profile1.0
body {"@id":"https://example.item/id/123", "hello":"world", "new_obj_state":{...}}
```

**Success Example 1.1**
A client POSTs a JSON document conforming to the JSON schema http://storedev.rerum.io/profile1.0 and thus is expecting a response under that same schema. The server answers that it has provided the response under the requested schema
```HTTP
Request:
POST /v1/create HTTP/1.1
Content-Type: application/json; profile="http://storedev.rerum.io/profile1.0"
body {"hello":"world"}

Response:
HTTP/1.1 201 Created
Content-Type: application/json; profile="http://storedev.rerum.io/profile1.0
Accept-Profile: http://storedev.rerum.io/profile1.0
body {"@id":"https://example.item/id/123", "hello":"world", "new_obj_state":{...}}
```

**Failure Example 1**
A client POSTs a JSON document conforming to the JSON schema http://storedev.rerum.io/profile1.0. The server answers that it cannot provide a response that respects the requested schema and so does not perform the POST.
```HTTP
Request:
POST /v1/create HTTP/1.1
Content-Type: application/json
Profile: http://storedev.rerum.io/profile1.0
body {"hello":"world"}

Response:
HTTP/1.1 406 Not acceptable
Content-Type: application/json
Accept-Profile: http://storedev.rerum.io/profile1.1
```

**Failure Example 1.1**
A client POSTs a JSON document conforming to the JSON schema http://storedev.rerum.io/profile1.0. The server answers that it cannot provide a response that respects the requested schema and so does not perform the POST.
```HTTP
Request:
POST /v1/create HTTP/1.1
Content-Type: application/json; profile="http://storedev.rerum.io/profile1.0"
body {"hello":"world"}

Response:
HTTP/1.1 406 Not acceptable
Content-Type: application/json; profile="http://storedev.rerum.io/profile1.1"
```

**Failure Example 2**
A client PUTs a JSON document conforming to the JSON schema http://fancy.funky.schema/profileFunk. The server answers that it cannot provide a response that respects the requested schema and so does not perform the PUT.
```HTTP
Request:
PUT /v1/update HTTP/1.1
Content-Type: application/json
Profile: http://fancy.funky.schema/profileFunk
body {"@id":"https://example.item/id/123", "goodbye":"world"}

Response:
HTTP/1.1 406 Not acceptable
Content-Type: application/json
Accept-Profile = http://storedev.rerum.io/profile1.0, http://storedev.rerum.io/profile1.1
```

**1.0 Properties Added to Responses**
- `new_obj_state` : Contains the entire JSON object duplicated inside this property
- `code` : The HTTP response code from the request (ex. 201)
- `iiif_validation` : The response object from the IIIF Validation endpoint. *Note this seems to be deprecated. We only ever return a JSON object saying we skipped it. Apps do not appear to ever try to use it.
- `original_object_id` - The id of the object before any updates or patches are performed
- `previously_released_id` - The releases.previous of the object being released
- `next_releases_ids` - The releases.next of the object being released
- `new_resources` - An array of JSON objects from a batch action

**Which Endpoints Need Which Properties?**
- _/create_ should add `code`, `new_obj_state`, and `iiif_validation`
- _/bulkCreate_ should add `code` and `new_resources`
- _/update_, _/patch_, _/set_, _/unset_ and _'internal import'_ should add `code`, `new_obj_state`, `iiif_validation`, and `original_object_id`
- _/overwrite_ should add `code`, `new_obj_state`, and `iiif_validation`
- _/release_ should add `code`, `new_obj_state`, `previously_released_id`, and `next_releases_id`
- ~~_/delete_~~ does not have any special property handling, it just returns 204 with an empty body
- ~~_/id_~~ and ~~_/getByProperties_~~ do not have any special property handling. They are 200s with either JSON or a JSONArray in the body.

The default requests will be considered `1.1`. If a user does not provide a Profile header, then there responses will be under the 1.1 syntax which _MAY_ cause their apps to break. Broken apps will need to update their code to pass the Profile header with the requests.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.