Skip to content
der edited this page May 17, 2015 · 71 revisions

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:hasMemberRelation 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:hasMemberRelation or ldp:isMemberOfRelation 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
  • text/csv

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
  • &_format=csv for text/csv

CSV Format

Both items and registers can be downloaded in a CSV format. Note that the CSV format does not support arbitrary RDF structure. It allows for entities with tree structured blank nodes and can include minimal metadata (the status and notation of the corresponding RegsiterItem). It does not support circular blank node references, graphs or arbitrary item metadata.

The CSV export will contain a header plus a row for each entry in the register or plus a single row when exporting an single item. In both cases the columns, when exporting with metadata, will be:

  • @id for the URI of the entity
  • @status for the status of the item within its register
  • @notation for the reg:notation value of the item (i.e. it’s relative uri within the parent register)
  • zero or more columns with the RDF properties of the entity

When exporting without metadata the @status and @notation columns will be omitted.

The column names for the RDF properties and the cell values all support a simple encoding of RDF values based on Turtle:

Value Cell syntax
string string or 'string'
lang-tagged string 'string' @ en
number 1234.5
boolean true or false
typed value 'lexical'^^<type>
URI resource <uri> or prefix:local if a suitable prefix exists in the system prefix register
blank node [prop value; ... prop value;] only supports bNode trees, no circular or cross references allowed

Ambiguous strings are encoding using surrounding ' characters, unambigous strings omit these for ease of editing. A string is ambiguous if it meets the syntax for a number, a boolean or prefixed URI.

Properties with multiple values are encoded in a single cell using | to separate each value, || repesents a | character.

The same format can be used to POST or PUT registrations or updates, in particular see the edit operation below.

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}/_{item}?update&status=superseded&successor={successor-uri} 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.

The special case for superseded allows the caller to supply the manatorry successor value as part of a single call.

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).

In additional there is an administrator action to really delete an item or register tree. This is used to recover from erroneous actions and breaks the normal lifecycle. This is achieved by:

Operation Target Result
POST http://registry/{register}/{entity}?real_delete 204 if successful
404 if the register doesn’t exist

Batch update – “edit”

Recent addition.

It is sometimes necessary to perform bulk updates to the contents of a register. This is supported through the use of an ?edit operation which combines the functionality of PATCH and PUT applied to multiple entries within a single register.

Operation Target Payload Result
POST http://registry/{register}/?edit A set of entities, optionally plus associated RegisterItems, in any RDF encoding (including CSV) 204 if successful, 400 if the payload is not valid,
404 if the register doesn’t exist

Each item in the payload is treated as either a new registration or a patch to an existing registration.

If the item already exists within the register then the entry is patched. For each property of the entity given in the payload then all the existing values of that property are removed from the registration and replaced by the value or values in the payload. Any property of the entity which is not included in the payload but is present in the current registration is left unchanged.

It explicit RegisterItems are including in the payload then the properties of any existing corresponding items will be similarly patched. In particular, if the RegisterItem includes a status value (e.g. an @status column in a CSV) then the status of the entry will be updated to match.

If the item exists within the register and neither the entity nor the item will be changed by this patch operation then no patching is performed and the version number of the item will be unchanged.

The combination of CSV format and this batch edit operation makes it easy to perform batch management of a register. The existing contents can be downloaded (optionally with metadata), edited within any spreadsheet program that can handle the CSV format, and then uploaded through the edit operation.

Within the user interface the term “patch” is used for this operation to distinguish it from interactive form-based editing.

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: graph registration

It is sometimes convenient to register, along with an entity, a graph of further descriptive statements.

An example of this is registering an entire ontology where the classes and properties in the ontology have # URIs relative to the ontology itself. It can be useful to register the ontology as an entity with the registry but also have the corresponding # URIs resolve.

This is supported through use of the ?graph keyword to indicate that the entity is described via an entire RDF graph and not simply a single resource description.

Operation Target Payload Result
PUT http://registry/{register}/{ont}?graph RDF graph including a conformant description of the root entity http://registry/{register}/{ont} 201 Created

The uploaded graph will be stored in its entirety as the entity description. A GET query (with conneg to RDF) will return that graph.

Since the graph can contain arbitrary other statements the identification of the intended root is tricky. For this reason the option is limited to a PUT at the intended root URI and the uploaded graph must contain a root entity corresponding to that URI. Use of relative URIs in the payload is not supported in this case.

Advanced: import export

Operation Target Payload Result
GET http://registry/_{register}?export A dump of the register and its tree of contents as application/n-quads
PUT http://registry/_{register}?import prior export 204 if successful

This pair of operations allows the state of a register tree to be saved and later reinstated. It can be used as a form of selective backup or to transfer state from a master registry to replicas. It could also be used for batch repairs to the register tree if the export is modified prior to reimport.

The export will contain the items and corresponding entity graphs for all versions of the register and its contents (recursively). The import process will delete all the current state of the register tree and replace it by the upload payload.

N.B. The import operation has a global effect, upload of a payload other than a direct export could result in irreparable damage to the registry contents.

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.
POST http://registry/{register}/?edit A set of entities or entities plus associated RegisterItems in any RDF encoding (including CSV) New items in the payload are registered, existing items are patched

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
GET http://registry/_{register}?export A dump of the register and its tree of contents as application/n-quads
PUT http://registry/_{register}?import prior export Replaces the current register tree by the exported state, returns 204 if successful

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
Clone this wiki locally