-
Notifications
You must be signed in to change notification settings - Fork 9
Api
- API approach
- Register access
- Registration
- Item and entity retrieval
- Content negotiation
- CSV format
- Item and entity update
- Register management
- Search and discovery
- Validation
- Advanced: tagging registers
- Advanced: graph registration
- Advanced: import/export
- Summary
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.
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
)
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 ) |
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 usingldp:hasMemberRelation
or it will default tordfs:member
. - Each of the
reg:Register
andreg: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’sreg: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 codesreg:statusSubmitted
orreg: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 |
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.
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 behttp://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 behttp://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 areg: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.
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.
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 toreg: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 therdfs:label
(s) of the submitted entry - the
dct:description
is set to thedct: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
andreg:operatingLanguage
will all be copying from the parent register unless explicitly set in the registration payload. - The
void:uriLookupEndpoint
,void:uriSpace
andvoid: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.
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
andrdfs:label
(in the case ofrdfs: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.
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.
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.
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
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.
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 (pathreg: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 inreg: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
andreg:predecessor
) and therdf:type
of the entity must match those already registered. While the item is inreg:statusSubmitted
such properties are still mutable. - Properties of the
reg:RegisterItem
that are maintained by the registry (reg:dateSubmitted
andreg:definition
) cannot be changed. A compound payload containing both a register item and an entity definition may use a blank-node for thereg:EntityReference
and the registry service will allocate an appropriate URI itself. - The
rdf:type
of the entity must match thereg: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.
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
.
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 |
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.
The creation, update and deletion of registers is similar to that for entities and follows the LDP pattern for containers.
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.
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.
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 |
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
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 |
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 descriptions404 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.
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.
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.
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 |
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 |
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 |
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 |
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 |
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. |
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 |
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 |
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 |
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 |