Changes
Requesting changes
A single inbox endpoint accepts mutations to the Knowledge Graph of a Pod and can be used to insert or delete RDF data.
Insert mutation
For example, the following operation writes some RDF statements as JSON-LD into the pod of Alice.
POST http://localhost:8080/alice/changes
Content-Type: application/ld+json
Request body:
This should immediately return a 201 Created
response. The Kvasir Knowledge Graph follows an eventual consistency model, so the changes may not be immediately visible in queries. However, the response will contain a Location
header, which refers to the change request resource. This resource can be queried to check the status of the change request ( see Reviewing a specific change).
Delete mutation
Delete mutations work similarly to insert mutations, but with a different keyword. For example, the following operation removes John's email-address from the pod of Alice.
POST http://localhost:8080/alice/changes
Content-Type: application/ld+json
Request body:
Assertions
Sometimes it can be useful to only transact a change request if a certain condition holds. For example, the following operation only inserts the statement if the email address of Alice is not already known.
POST http://localhost:8080/alice/changes
Content-Type: application/ld+json
Request body:
Note the kss:assert
keyword, which is followed by an array of assertions. Each assertion must specify the type of assertion and a GraphQL query (see Querying) that should return an empty result (in case of type kss:AssertEmptyResult
) or a non-empty result (in case of type kss:AssertNonEmptyResult
). If one of the assertions fails, the entire transaction is discarded.
Use the URL returned via the Location
header to check the status of the change request. When the change resource is available on the server (remember: eventual consistency), you should see a resultCode
of ASSERTION_FAILED
.
With clause
The kss:with
keyword can be used to bind a set of variables that can be used in the insert and delete operations. For example, the following operation binds the id of a Person with the first name Alice
and then uses this id to add some additional personal information in the insert operation:
POST http://localhost:8080/alice/changes
Content-Type: application/ld+json
Request body:
The with-clause value is a GraphQL query (see Querying). The results of this query can be referenced in the insert and delete operations using JSONata template strings. JSONata is a powerful JSON query and transformation language (inspired by XPath for XML) which allows the user to construct the data that needs to be deleted or inserted in a flexible way.
The expression in the example above operates on the result-set of the with-query at the time the change request is processed. Conceptually you could think of this being the following JSON object:
You can then write a JSONata expression that extracts the id
from the first element of the array and uses it in the insert operation to add a triple with predicate ex:knows
, referencing the Person with id ex:john
.
Use the URL returned via the Location
header to check the status of the change request. When the change resource is available on the server, you should see a resultCode
of COMMITTED
. To review the actual content that was inserted or deleted via the with-clause, you can view details by appending the path /records
to the change request URL (see also: Reviewing a specific change).
Delete wildcard
In addition to JSONata expressions in the insert and delete operations, the kss:delete
operation also supports a wildcard expression. For example, the following operation deletes all triples that match the with-clause of the change request.
POST http://localhost:8080/alice/changes
Content-Type: application/ld+json
Request body:
Change history
A full log of the changes made to a pod's Knowledge Graph can be retrieved by querying the changes endpoint.
GET http://localhost:8080/alice/changes
Accept: application/ld+json
This should return a 200 OK
response with a JSON-LD object containing the change history of the pod.
Reviewing a specific change
You can query the status of a specific change request.
GET http://localhost:8080/alice/changes/f65997cb-80c2-466e-82f1-03ea48d72a91
Accept: application/ld+json
This should return a 200 OK
response with a JSON-LD object containing the details of the change request.
In this case the resultCode is COMMITTED
, which means the change request was successfully processed. Other possible values are:
ASSERTION_FAILED
: The Change Request was not applied because one or more assertions failed.NO_MATCHES
: The Change Request was not applied because the with-clause did not return any results.TOO_MANY_MATCHES
: The Change Request was not applied because the with-clause returned too many results.VALIDATION_ERROR
: The Change Request was not applied because of a validation error.INTERNAL_ERROR
: The Change Request was not applied because of an internal error.
In case of an error, the response will contain an errorMessage
field with a description of the error.
To review the actual content that was inserted or deleted, you can view details by appending the path /records
to the change request URL.
GET http://localhost:8080/alice/changes/f65997cb-80c2-466e-82f1-03ea48d72a91/records
Accept: application/ld+json
This should return a 200 OK
response with a JSON-LD object containing the records that were inserted or deleted.
Streaming changes
You can subcribe to changes in a pod by using the changes endpoint with the Accept: text/event-stream
header. This will return a stream of Server-Sent Events (SSE), containing the changes that are being made to the Pod in near-realtime.
GET http://localhost:8080/alice/changes
with header Accept: text/event-stream
This will return a stream of events, where each event is a JSON-LD instance containing information on changes made to the Pod's Knowledge Graph.