Skip to content
der edited this page Mar 27, 2015 · 48 revisions

Maintance of the Linked Data Registry documentation has moved to registry-core.wiki

Table of contents

Design approach

The access and update API for registers follows the pattern for Linked Data Platform Collections (LDPC) as described in the first working draft http://www.w3.org/TR/2012/WD-ldp-20121025/

We recognise that the LDPC specification is subject to change, and indeed have a number of reservations about the design. However, it provides a starting point for container management. We make no commitment to track changes to the LDPC specification as they occur. The degree of compatibility with the emerging standard should be reviewed at the end of the proof-of-concept phase.

All resources available from the registry are delivered as RDF. Content negotiation can be used to choose between RDF/XML (application/rdf+xml) and Turtle (text/turtle) formats. We MAY also support JSON-LD (application/ld+json). Conversely updates to such resources consume an RDF payload and the registry supports the same range of MIME types for update.

Register access

For this and subsequent sections we will use the abbreviation http://registry/{register} to indicate some specific register in the registry. Where registry represents whatever the base URI is for the registry e.g. location.data.gov.uk.

This is not meant to imply a restriction to only top level registers and the operations described applying equally to sub-registers (http://registry/{principle-register}/../{sub-register}) and to the root register (http://registry)

Reading a register

The basic operation for reading a register is:

Operation Target Result
GET http://registry/{register} 404 if no such register
200 with RDF describing the register along with its visible members (those in state reg:statusAccepted)

API Example: register read

As shown in the example the returned payload comprises a description of the register resource, linked by a membership property to zero or more entries in the register.

The internal representation of the registry state is complicated by several factors:

  • The status of an entry in a register is represented by a metadata record (reg:RegisterItem). For simplicity the default view of a register omits these metadata records and just shows registered entities themselves, linked directly from the register via an inferred membership property. The membership property used for a register may be declared using ldp:membershipPredicate or it will default to rdfs:member.
  • Each of the reg:Register and reg:RegisterItem resources is versioned using a pattern of hub (version:VersionedThing) and version (version:Version) resources described in Principles and concepts#wiki-history. The default response merges the hub resource with the latest version and omits the versioning representation.
  • Multiple verisons of each entity description may be held by the repository. The reg:EntityReference value of the item’s reg:definition indicates the correct description associated with a given version of the item. Internally the registry service normally uses named graphs (or an equivalent) to separate the different description versions. Though some implementations may allow registered entities to themselves be explicitly versioned by adding them to the versionedTypes register. In either case the default register view unpacks the entity reference and simply shows the most recent version of the entity.
  • Items with a status code of reg:statusNotAccepted (or rather one of its narrower status codes reg:statusSubmitted or reg:statusInvalid) are not yet members of the container and do not appear in default view.

There are a number of resources associated with a register that can be used to vary the view retrieved:

Operation Target Result
GET http://registry/{register}?non-member-properties Just the metadata for the register itself, no listing of members [example]
GET http://registry/{register}?firstPage
http://registry/{register}?_page=0
The register metadata and just a page of entries, following the LDPC paging protocol, [example]
GET http://registry/{register}?status={status} Register description, listing all members whose status has skos:prefLabel '{status}' and sub-statuses thereof (e.g. a request for reg:statusValid will return entities with status reg:statusValid, reg:statusStable and reg:statusExperimental). The pseudo status “any” may be used as a wildcard to return all items, whatever their status.
GET http://registry/{register}?_view=with_metadata Includes the explicit reg:RegisterItem instances showing the status of each entry [example]
GET http://registry/{register}:{version} Return a particular version of the register.
GET http://registry/_{register}?_view=version_list Return the RegisterItem describing the register, together with a list of versions of that item. For each version the time interval over which it was valid is included.
GET http://registry/{register}?_versionAt={dateTime} Return the version of the register that was in effect at the given xsd:dateTime; shows the explicit hub/version resources

Registration

Operation Target Payload Result
POST http://registry/{register} RDF description of the entity to be registered, optionally including a skeleton registry item for it. 201 with Location header set to RegisterItem created as a result of the registration
400 if the payload is not valid (which may mean it failed a validation query)
401 if the user is not authorized to add entries to this register
403 if the entity already exists
404 if the target register does not exist

In the common case (called simple below) the RDF payload supplied to the POST contains a set of statements about a single root resource, which is the entity being registered. An advanced usage (compound payload) is also supported in which the payload also contains a description of a reg:RegisterItem whose reg:definition / reg:entity reference indicates the entity being registered, whose description is also included in the payload. This allows the submitter to specify information associated with the register item itself including license information and an initial status. In particular, this makes it possible for the submitter to choose a particular URI for the register item itself even when the entity is external – noting the constraint enforced by the registry that the URIs for all register item require the last segment of the URI path to be prefixed with an underscore “_” character.

Notation and entity URI

In processing the registration request the registry needs to two pieces of information – the identity (URI) for the entity being registered and a local identifier (reg:notation, scoped to the register). The registry service supports both automatic allocation and explicit assignment of these identifiers. There are several cases to consider:

If the payload is simple:

  • if the entity description is given using an absolute URI that is not a direct child of the target register then that URI will be used for the entity to be registered and the registry will auto-assign a notation value
  • if the entity description is given using an absolute URI that is a direct child of the target register then that URI will be used for the entity to be registered and the registry set notation as the last segment of the URI path
  • if the entity description is given using a relative URI <{entity}> then the URI used for the entity will be http://registry/{register}/{entity} and the notation will be {entity}
  • if the entity description is given using an empty relative URI <> then a notation will be auto-assigned and the URI used for the entity will be http://registry/{register}/{notation}

If the payload is not simple, i.e. it supplies both a register item and an associated entity description, then the entity URI is given explicitly in the payload (or is a blank node, see below) and the notation will be determined as follows:

  • if the item URI is absolute and not an immediate child of the register then reject with code 400
  • if the item URI is absolute and within the register namespace then the notation will be found by stripping an initial “_” character from the last segment of the URI path (if there is no “_” reject with code 400)
  • if the item URI is a relative URI <_{item}> then the notation will be {item}
  • if the item URI is an empty relative URI <> then a notation will be auto-assigned unless it is explicitly provided a reg:notation value on the register item

Note that these rules apply in sequence so that if a payload provides both a non-empty item URI and an explicit reg:notation then the notation value derived from the item URI will be used and will override the supplied notation value.

In all cases if an item already exists in the register with the same notation the request will be rejected with code 403.

The URI of the new register item will be http://registry/{register}/_{notation}, which will be returned in the Location header of the http response.

It is up to the registry implementation what algorithms for auto-allocation are used. It is admissible to employ an algorithm where the notation is a number and the register allocates the next unused number. However, an approach based on generation of UUIDs or a hash of the supplied information is also admissible and may be appropriate for registry implementations designed to support distributed update.

API Example: registration

Reservation of register items

In some settings organizations wish to be able to reserve entries in a register with specific item identities (notations) before the final entity itself is specified. This is supported by use of the reg:statusReserved status flag. To reserve an entry register an item with this status and an entity definition comprising a blank node with the minimal mandatory properties. For example:

   <_six>  a  reg:RegisterItem ;
      dct:description "Reserved for future use"@en ;
      reg:definition [  reg:entity [a skos:Concept; rdfs:label "reserved"]  ] ;
      reg:status reg:statusReserved;
      .

Since the entity URI and properties may be amended while a item is still notAccepted then the entity corresponding to a reserved item can be added later by means of an update call.

Automatic properties

The act of registration automatically sets certain properties of the created reg:RegisterItem:

  • the dct:dateSubmitted is set to the date stamp of the submission as determined by the clock time of the registry service, this will replace any value explicitly supplied in registration request
  • the reg:status is set to reg:statusSubmitted unless this is explicitly provided in the registration payload
  • the reg:notation value is set to the notation determined by the above algorithm unless this is explicitly provided in the registration payload
  • the reg:itemClass is set to the type(s) of the submitted entry
  • the rdfs:label is set to the rdfs:label(s) of the submitted entry
  • the dct:description is set to the dct:description(s) of the submitted entry, if any
  • the reg:submitter may be set automatically to an identifier for the user making the submission

Except where noted then any values for these properties explicitly supplied as part of the request payload will augment those derived from the entity description.

Note: that this permits the submitter to provide an initial reg:status other then reg:statusSubmitted. This is useful in cases where approval has already been granted before the registration. The register manager my block this option through use of validation queries.

The act of registering a register will also automatically set certain properties of the register:

  • The reg:owner, reg:manager, reg:license, reg:governancePolicy and reg:operatingLanguage will all be copying from the parent register unless explicitly set in the registration payload.
  • The void:uriLookupEndpoint, void:uriSpace and void:openSearchDescription will be automatically set based on the registry API patterns for these services.

Note that the dct:modified and void:exampleResource properties will also be maintained as items are registered within the register.

Validation of registration

The registry service will validate the submitted entity and reject the request with code 400 if the entity description is not valid. The validation checks are listed below.

  • The submission must be syntactically valid.
  • The entity must have at least one value for each the mandatory properties rdf:type and rdfs:label (in the case of rdfs:label there must be a value within an operating language of the register).
  • If the submission is a referenced entity which falls within the namespace of the registry (but outside that of the target register) then it must already exist (external referenced entities are not required to resolve at time of submission).
  • If the register declares one or more SPARQL ASK validation queries (reg:validationQuery) then all of those queries, when applied to the submitted graph, must return false.

All customization of the technical validation is done through declaration of validation queries.

Batch registration

The advanced usage also permits bulk registration of items by including multiple reg:RegisterItem instances, and multiple entities, within a single POST call. In that case the returned Content-Location header will be to the register itself. This mode does not support automatic allocation of URIs since the root resource would then be ambiguous.

A special case of bulk registration is supported to enable easy publication of collections such as ontologies or complete SKOS collections and concept schemes. This is supported through two additional register resources:

Operation Target Payload Result
POST http://registry/{register}?batch-referenced[&status=state] An RDF description of a collection with initial members 201 if successful in creating a sub-register for the collection with some initial members
400 if the request is not valid
404 if the target register does not exist
POST http://registry/{register}?batch-managed[&status=state] As above As above

In each case the payload is an RDF description of an instance of a collection type which has been registered in the /system/bulkCollectionTypes register, plus a set of members of that collection (member resources). The ldp:membershipPredicate or reg:inverseMembershipPredicate declared in the bulk collection types registration is used to locate the intended members of the collection within the payload. If those predicates are also given in the payload then they override the registered default.

The two resources differ in how validation of member resources is treated. The shared payload validation requirements are:

  • The payload must contain one and only one instance of a registered bulk collection types, the collection resource.
  • The collection resource URI must be a valid immediate child of the target register (whether specified as an absolute or relative URI).
  • The payload must be an internally consistent collection description, all non-blank resources in the payload other than the collection itself must be members of the collection.

In the case of a batch-referenced request then any internal references will be checked to verify they exist and the mandatory properties of those internal references will be fetched to form the content of the referenced entity definition.

In the case of a batch-managed request then each member resource must have a URI which is an immediate child of the collection resource (whether relative or absolute) and must have the mandatory properties for registration (rdf:type and rdfs:label).

In both cases, if the payload is valid, the collection resource is registered as an entity within the register and is itself marked as being a register, thus creating a new sub-register http://registry/{register}/{collection-root}. A register item is created within that sub-register for each declared initial member of the collection, each will thus have an item URI http://registry/{register}/{collection-root}/_{item-i}. In the case of a batch-managed request then each member resource will have URI http://registry/{register}/{collection-root}/{entity-i}.

The reg:owner of the created sub-register will be the first found of:

  • a reg:owner property on the collection resources,
  • a dct:publisher property on the collection resource,
  • the user submitting the request.

In both cases an optional status={status} parameter may be used to set the initial status of the member resources within the collection sub-register.

The batch-managed operation is particular useful for registering a complete ontology or a complete SKOS collection or concept scheme while making the terms within those collections visible and maintainable through the normal registry API.

The batch-referenced operation is useful when the terms already exist, e.g. in a separate register in the repository and the need is to simply create a new maintained collection of a subset of those terms.

Item and entity retrieval

Each entity within the registry’s namespace acts as a Linked Data resource and resolves to return an RDF graph including a description of the entity.

Operation Target Result
GET http://registry/{register}/{entity} Return the entity.
GET http://registry/{register}/{entity}?_view=with_metadata Return the entity plus the reg:RegisterItem describing it.
GET http://registry/{register}/_{item} Returns both the register item (with versioning hidden) and the corresponding entity.
GET http://registry/{register}/_{item}:{version} Returns a specified version of the register item along with the corresponding entity referenced in that version of the register item.
GET http://registry/{register}/_{item}?_view=version_list Returns the RegisterItem together with information on each known version of the item. Each version includes the interval over which it was valid, which version (if any) it replaced and whether it is the current version of the item. API Example: version_list

In each case if the item does not exist a 404 status code will be returned.

In addition it is possible to request an entity description, including an external entity, through a request to the register. This will check all sub-registers of the target register to attempt to locate the item. This call is useful for validating if an entity is registered.

Operation Target Result
GET http://registry/{register}?entity={uri} 200 if the entity is known to this register sub-tree and visible, returned payload gives the entity description
404 if the entity is not found or not visible
GET http://registry/{register}?entity={uri}&status={status} 200 if the entity is known to this register sub-tree and has a status skos:prefLabel '{status}', returned payload gives the entity description. The pseudo status “any” may be used as a wildcard to return all items, whatever their status.
404 if the entity is not found or does not have that status code

The _view=with_metadata view modifier is supported.

Note that as an entity may be a member of multiple registers, searching for a specific entity with the _view=with_metadata view modifiers specified may return multiple register items; one for each register that the entity is a member of.

The register may contain federated registers in which case the entity search will also be passed to the federated registry and the results of that search will be included in the final result payload. Federated search can be suppressed by adding the query parameter federated=false.

Functions such as searching for back-links (e.g. which resources refer to a given entity), aggregation of back-links for a given entity and ping-back (e.g. notify an owner each time an entity is proposed as a member of a register enabling the tracking of usage) are noted as useful additions to the registry capability but are considered outside the scope of this proof of concept.

Implementation note: The implied search over sub-registers is potentially expensive, an interval (?) coding scheme may be needed to for high performance sub-tree testing.

Content negotiation

All GET requests normal http content negotiation to select the RDF representation to return.

Implementations must support at least mime types:

  • text/turtle
  • application/rdf+xml

Implementations may in addition support:

  • application/ld+json

The same Content Types should be supported for PUT and POST entity bodies.

As a convenience for examining data from a web browser it is possible request a particular format in any get request by using the parameter:

  • &_format=rdf for application/rdf+xml
  • &_format=ttl for text/turtle
  • &_format=jsonld application/ld+json

Item and entity update

As described in Principles and concepts#wiki-history it is possible to change a registered entity in non-essential ways. This is supported by using PUT or PATCH to update registered entities.

Similarly it is possible up change the metadata in a register item through PUT and PATCH to the item.

Managed entities may be updated directly or via the associated register item, whilst referenced entities may only be updated via the register item.

Operation Target Payload Result
PUT http://registry/{register}/{entity} Modified entity definition in RDF 204 if successful
404 if the item doesn’t exist
400 if the payload is not valid or the resource URI in the payload does not match the entity being updated
401 if the user is not authorized to add entries to this register
403 if the request attempts to modify an immutable or system property
412 if request includes If-match and the etags don’t match
PATCH http://registry/{register}/{entity} Partial entity definition in RDF As for PUT except any existing value for a property which is not mentioned in the PATCH payload is retained.
PUT http://registry/{register}/_{item} Modified register item in RDF, optionally including modified entity definition. 204 if successful
404 if the item doesn’t exist
400 if the payload is not valid or the resource URI in the payload does not match the item being updated or the payload does not contain a register item at all
401 if the user is not authorized to add entries to this register
403 if the request attempts to modify an immutable or system property
412 if request includes If-match and the etags don’t match
PATCH http://registry/{register}/_{item} Partial item definition in RDF, optionally including partial modified entity definition As for PUT except any existing value for a property which is not mentioned in the PATCH payload is retained. This is the preferred means to update item metadata.

Each update will create a new version of the RegisterItem and, if the entity is changed, a new version of the entity.

Note that item update allows compound updates which include a change to the registered definition of the entity as well as to the register item metadata. This allows external entity definitions to be updated.

The PATCH operation with an RDF payload is intended to allow simple selective modification. If the PATCH payload includes one or more values for property p on the subject resource then all existing values for p will be removed and all the supplied values will be used in their place. For example, labels will often be supplied in multiple languages, in that case a PATCH payload to change the label must supply the change in all the supported languages simultaneously.

A number of validation checks on the PUT/PATCH request must be made before the change is carried out. If any check fails the whole operation will be rejected with status code 403 or 400 (depending on the error) and no change to the registry state will be made. These checks are:

  • The URI of the register item, if present in the payload, must match the register item being modified.
  • If the item is in a reg:statusAccepted state then the entity URI (path reg:definition / reg:entity) must match the registered entity URI, a change of the URI of an external referenced entity is permitted while the item is in reg:statusSubmitted. Once an external referenced entity has been accepted then changing its URI is not permitted, a new item would have to be registered for the new entity and marked as superseding the old item.
  • If the item is in a reg:statusAccepted state then the all rigid values of the register item (reg:notation, reg:register, reg:itemClass and reg:predecessor) and the rdf:type of the entity must match those already registered. While the item is in reg:statusSubmitted such properties are still mutable.
  • Properties of the reg:RegisterItem that are maintained by the registry (reg:dateSubmitted and reg:definition) cannot be changed. A compound payload containing both a register item and an entity definition may use a blank-node for the reg:EntityReference and the registry service will allocate an appropriate URI itself.
  • The rdf:type of the entity must match the reg:containedItemClass specification(s) in the register (if any).
  • Any validation queries declared on the register must pass. The registry service must simulate the any PATCH operation and create an RDF graph containing the proposed final state of the register item and registered entity and then run the validation query on that simulated state.

Status update

The most common time that a register item needs to be modified is to update its status. A convenience operation is available to perform this action:

Operation Target Payload Result
POST http://registry/{register}/_{item}?update&status={status} Empty 204 if successful
404 if the item doesn’t exist
401 if the user is not authorized to add entries to this register
POST http://registry/register}?update&status={status} Empty Updates the status of each Register item contained in the register. Return codes as above.

The {status} should be the skos:prefLabel of the corresponding reg:Status resource.

Note that setting the status may result in the change of state in the associated register:

  • specifying status as reg:statusAccepted or sub-statuses thereof (e.g. if the entity is accepted by the register manager) will assert that the entity is an accepted member of the register; whilst
  • specifying status as reg:statusInvalid will invalidate an entry in the register (e.g. if the entity is deemed to have a substantive error) – effectively removes the entity from the register (e.g. the entity is no longer considered to be a member of the register).

Setting the status to reg:statusAccepted will trigger an additional verification test to ensure that the entity itself has a valid URI and is not a blank-node. This is to prevent reserved items being prompted to accepted status before the intended entity has been submitted.

Specifying the status as reg:statusInvalid has the same effect as a DELETE request for the associated entity.

In addition to updating the status setting the registry will also update any relevant date stamps. Setting the status from reg:statusSubmitted to any reg:statusValid status will set dct:dateAccepted.

The registry should enforce lifecycle constraints on status update (e.g. a status cannot be updated from reg:statusSuperseded to reg:statusValid). When setting the status of an entire register then items which cannot be updated will be skipped.

There will be occasions when a status is set erroneously and it will be necessary to reset the status despite the lifecycle constraints. This is support through the use of an additional &force parameter which is accessible only to suitably authorized administrator.

Note: There is one additional status update behaviour supported. If a register item is updated to say that it supersedes an existing item (reg:predecessor) the superseded register item will be automatically marked with reg:statusSuperseded.

Deletion

It is also possible to delete an internal entity or the register item:

Operation Target Result
DELETE http://registry/{register}/{entity} 204 if successful
404 if the register doesn’t exist
DELETE http://registry/{register}/_{item} 204 if successful
404 if the register doesn’t exist

Deleting an entity or register item does not remove it but sets its status to reg:statusInvalid which results it being hidden and will not appear in normal register listings or entity searches.

The registry should enforce lifecycle constraints on status update (e.g. status can no longer be amended once it has been set to reg:statusInvalid).

Register management

The creation, update and deletion of registers is similar to that for entities and follows the LDP pattern for containers.

Create a sub-register

Operation Target Payload Result
POST http://registry/{register} Register definition in RDF 201 with Location header set to new entity
403 if the register already exists
404 if the parent register does not exist
401 if the user is not authorized to create new registers

Just as with registration of items the URI in the POSTed register definition may be:

Absolute URI <http://registry/register/subreg> Accept if name is within parent register and not already used
Relative URI <subreg> Treat as a notation value for new register, accept if not already used.
Empty relative URI <> Allocate a new notation value

The act of creating a new register will automatically add a reg:subregister link to the principal register.

Note that there are no restrictions on the register to which a sub-register is added. In particular, it is legitimate (though potentially confusing) for a register to contain a mix of simple entities and sub-registers. The register manager may use validation queries to limit this freedom.

Update register metadata

Operation Target Payload Result
PUT http://registry/{register}?non-member-properties Modified register definition in RDF 204 if successful
404 if the register doesn’t exist
412 if request includes If-match and the etags don’t match
PATCH http://registry/{register}?non-member-properties Partial modified register definition in RDF As for PUT but only properties included in the PATCH payload will be changed.

Note that if the ?non-member-properties query parameter is omitted, the request shall be rejected; the intent is to indicate that only the ‘non-member properties’ may be updated using the PUT or PATCH; membership is amended through other mechanisms.

Delete a register

Operation Target Result
DELETE http://registry/{register} 204 if successful
404 if the register doesn’t exist

Deleting a register does not remove it but sets its status to reg:statusInvalid.

Registers support free text search over the labels for entities in the register or in any nested sub-registers. The API supports filtering on other properties of the metadata.

Operation Target Result
GET http://registry/{register}?query={text}[&{key}={value}] An RDF graph formatted as a LDP page of results with one entry for each matching entity
GET http://registry/{register}?query={text}&_view=with_metadata[&{key}={value}] As above but the graph includes the reg:RegisterItem for each matched entity

API Example: search

Note that if _view=with_metadata is specified the result graph has sufficient information to determine which sub-register each result appears in.

The {text} search target supports Lucene search syntax.

The optional {key}={value} pairs allow filtering of the search based on the RDF property of either the RegisterItem or the entry itself. The key should be a curie using one of a predefined set of available prefixes (rdf, rdfs, owl, dct, reg, skos). The value will be treated as a URI if begins with http[s]: otherwise it will be treated as a literal. For the literal case the search value will be matched against the lexical form of the stored literals (ignoring any language or datatype).

The register may contain federated registers in which case the search will also be passed to the federated registry and the results of that search will be included in the final result payload. Federated search can be suppressed by adding the query parameter federated=false.

In addition to text search the registry supports SPARQL 1.1 query to the registry triple store. The SPARQL endpoint is defined to be:

http://registry/system/sparql

This supports the SPARQL 1.1 query protocol

Validation

The fetch operation http://registry/{register}?entity={uri} supports testing the existence of a single entry. For bulk validation the registry provides a means to test whether all of a set of URIs are registered and visible within a register or its sub-registers.

Operation Target Payload Result
POST http://registry/{register}?validate List of entry URIs to validate, one per line. 204 if validation was successful for all supplied URIs
404 if the register doesn’t exist
400 if one or more entries fail to validate
POST http://registry/{register}?validate={uri1}&validate={uri2}&... Empty body, URIs to validate are given by the query parameters. 204 if validation was successful for all supplied URIs
404 if the register doesn’t exist
400 if one or more entries fail to validate

Advanced: tagging registers

Note: this is an experimental facility which is not yet fully developed. The current implementation provides for non-recursive tagging. An investigation is planned to determine whether this is the right approach or whether other mechanisms might achieve the underlying goal.

It is convenient to be able to capture the state of a register at a given time in order to be able to refer to it. For example a specification might require use of all codes in a register as defined on a particular date.

Operation Target Payload Result
POST http://registry/{register}?tag={tag} empty 204 and internally a prov:Collection is generated capturing the state of the register at this time
GET http://registry/{register}?tag={tag} empty 200 returning an RDF graph containing the prov:Collection and the associated register items and entity descriptions
404 if there is not such tag (or no such register)

The format of the tagged collection is best explained through an example. Assume a register http://registry/reg1, currently on version 5, containing three items with associated entities.

Then the result of a call:

POST http://registry/reg1?tag=mytag

would be to add the following to the store:

<http://registry/reg1> a reg:Register, version:VersionedThing ;
    reg:release  <http://registry/reg1?tag=mytag> ;
.
<http://registry/reg1?tag=mytag> a prov:Collection;
    reg:tag "mytag";
    prov:generatedAtTime  "2012-11-11T09:40:00Z"^^xsd:dateTime ;
    prov:wasDerivedFrom  <http://registry/reg1:5>;
    prov:hadMembers <http://registry/reg1/_item1:2>, <http://registry/reg1/_item2:1>, <http://registry/reg1/_item3:1> ;
.

Note that the tagged collection is added to the hub resource for the register though the provenance shows which version of the register was tagged.

Note also that the members of the collection point to the specific versions of the items that were in the register at the time it was tagged. If one of these items is modified (e.g. to change its status or correct a label) then the register itself will remain on version 5 but will now show the modified item. Whereas the collection will still show the state of the item at the time of tagging.

Advanced: distributed management

Note: this section is out of scope for the PoC and so not fully developed.

It is desired to support distributed management of the registry whereby the state of a register can be downloaded by e.g. the register manager, updated locally and then at a later date the state merged back into the published register.

This made possible through two specialized API calls.

Operation Target Payload Result
GET http://registry/{register}?_view=snapshot Empty 200 with an RDF dataset, expressed in Trig syntax, containing a default graph with the current version of the register resource and associated register item resources plus a set of named graphs containing the graphs used in the entity reference
PATCH http://registry/{register} Trig graph as generated by a _view=snapshot call. 204 if the changed state was successfully merged
409 if there is a version conflict
404 if the register does not exist

The PATCH operation performs per-resource merge. For each resource (register and register item) it checks if the version in payload is later than that in the registry, or is new, if so the version in the registry can be safely replaced with the new version. If the resource has been modified in the registry since the snapshot was taken then the version conflict means that the update is aborted and code 409 returned. Either all of the updates succeed or the entire operation is aborted, no partial updates are made.

In this way it is possible for multiple distributed groups to add new items to a register or to update a registered item. A conflict only arises if two groups attempt to modify the same item (or the metadata of register itself). In that case a manual merge step would be required. This merge operation would be supported by client-side distributed update tools and is beyond the scope of the registry service.

Summary of API

Register read

Operation Target Result
GET http://registry/{register}?non-member-properties Just the metadata for the register itself, no listing of members [example]
GET http://registry/{register}?firstPage
http://registry/{register}?_page=0
The register metadata and just a page of entries, following the LDPC paging protocol, [example]
GET http://registry/{register}?status={status} Register description, listing all members whose status has skos:prefLabel '{status}' and sub-statuses thereof (e.g. a request for reg:statusValid will return entities with status reg:statusValid, reg:statusStable and reg:statusExperimental). The pseudo status “any” may be used as a wildcard to return all items, whatever their status.
GET http://registry/{register}?_view=with_metadata Includes the explicit reg:RegisterItem instances showing the status of each entry [example]
GET http://registry/{register}:{version} Return a particular version of the register.
GET http://registry/_{register}&_view=version_list Return the RegisterItem describing the register, together with a list of versions of that item. For each version the time interval over which it was valid is included.
GET http://registry/{register}?_versionAt={dateTime} Return the version of the register that was in effect at the given xsd:dateTime; shows the explicit hub/version resources

Registration

Operation Target Payload Result
POST http://registry/{register} RDF description of the entity to be registered, optionally including a skeleton registry item for it. 201 with Location header set to RegisterItem created as a result of the registration
400 if the payload is not valid (which may mean it failed a validation query)
401 if the user is not authorized to add entries to this register
403 if the entity already exists
404 if the target register does not exist

Batch registration

Operation Target Payload Result
POST http://registry/{register}?batch-referenced[&status=state] An RDF description of a collection with initial members 201 if successful in creating a sub-register for the collection with some initial members
400 if the request is not valid
404 if the target register does not exist
POST http://registry/{register}?batch-managed[&status=state] As above As above

Item and entity retrieval

Operation Target Result
GET http://registry/{register}/{entity} Return the entity.
GET http://registry/{register}/{entity}?_view=with_metadata Return the entity plus the reg:RegisterItem describing it.
GET http://registry/{register}/_{item} Returns both the register item (with versioning hidden) and the corresponding entity.
GET http://registry/{register}/_{item}:{version} Returns a specified version of the register item along with the corresponding entity referenced in that version of the register item.
GET http://registry/{register}/_{item}?_view=version Returns the RegisterItem with versioning information included and the entity.
GET http://registry/{register}/_{item}?_view=version_list Returns the RegisterItem together with information on each known version of the item. Each version includes the interval over which it was valid, which version (if any) it replaced and whether it is the current version of the item.
GET http://registry/{register}?entity={uri} 200 if the entity is known to this register sub-tree and visible, returned payload gives the entity description
404 if the entity is not found or not visible
GET http://registry/{register}?entity={uri}&status={status} 200 if the entity is known to this register sub-tree and has a status skos:prefLabel '{status}', returned payload gives the entity description. The pseudo status “any” may be used as a wildcard to return all items, whatever their status.
404 if the entity is not found or does not have that status code

Item and entity update

Operation Target Payload Result
PUT http://registry/{register}/{entity} Modified entity definition in RDF 204 if successful
404 if the item doesn’t exist
400 if the payload is not valid or the resource URI in the payload does not match the entity being updated
401 if the user is not authorized to add entries to this register
403 if the request attempts to modify an immutable or system property
412 if request includes If-match and the etags don’t match
PATCH http://registry/{register}/{entity} Partial entity definition in RDF As for PUT except any existing value for a property which is not mentioned in the PATCH payload is retained.
PUT http://registry/{register}/_{item} Modified register item in RDF, optionally including modified entity definition. 204 if successful
404 if the item doesn’t exist
400 if the payload is not valid or the resource URI in the payload does not match the item being updated or the payload does not contain a register item at all
401 if the user is not authorized to add entries to this register
403 if the request attempts to modify an immutable or system property
412 if request includes If-match and the etags don’t match
PATCH http://registry/{register}/_{item} Partial item definition in RDF, optionally including partial modified entity definition As for PUT except any existing value for a property which is not mentioned in the PATCH payload is retained. This is the preferred means to update item metadata.

Status update

Operation Target Payload Result
POST http://registry/{register}/_{item}?update&status={status} Empty 204 if successful
404 if the item doesn’t exist
401 if the user is not authorized to add entries to this register
POST http://registry/register}?update&status={status} Empty Updates the status of each Register item contained in the register. Return codes as above.

Item delete

Operation Target Result
DELETE http://registry/{register}/{entity} 204 if successful
404 if the register doesn’t exist
DELETE http://registry/{register}/_{item} 204 if successful
404 if the register doesn’t exist

Register management

Operation Target Payload Result
POST http://registry/{register} Register definition in RDF 201 with Location header set to new entity
403 if the register already exists
404 if the parent register does not exist
401 if the user is not authorized to create new registers
PUT http://registry/{register}?non-member-properties Modified register definition in RDF 204 if successful
404 if the register doesn’t exist
412 if request includes If-match and the etags don’t match
PATCH http://registry/{register}?non-member-properties Partial modified register definition in RDF As for PUT but only properties included in the PATCH payload will be changed.
DELETE http://registry/{register} Empty 204 if successful
404 if the register doesn’t exist

Search

Operation Target Result
GET http://registry/{register}?query={text}[&{key}={value}] An RDF graph formatted as a LDP page of results with one entry for each matching entity
GET http://registry/{register}?query={text}&_view=with_metadata[&{key}={value}] As above but the graph includes the reg:RegisterItem for each matched entity
http://registry/system/sparql SPARQL endpoint

Validation

Operation Target Payload Result
POST http://registry/{register}?validate List of entry URIs to validate, one per line. 204 if validation was successful
404 if the register doesn’t exist
400 if one or more entries fail to validate
POST http://registry/{register}?validate={uri1}&validate={uri2}&... Empty body, URIs to validate are given by the query parameters. 204 if validation was successful for all supplied URIs
404 if the register doesn’t exist
400 if one or more entries fail to validate