Ga naar hoofdinhoud

Facets

Introduction

A facet is a collection of categorized values to narrow down search results. For example, the creators of heritage objects can be organized into a 'Creator' facet.

Facets are tied to a heritage collection: they are returned in response to a search for entities in a specific collection and do not exist on their own.

Facets are an OPTIONAL extension. A data layer may choose whether or not to implement them.

notitie

To do: clarify the facet functionality: presentation layers not only want to retrieve the facets, they also want to be able to search and browse facets.

Facets

The data layer determines which facets to support. This specification does not require any specific facets.

For example, an API that exposes information about...

  1. paintings defines the facet 'Technique', to categorize the techniques used for creating the works of art;
  2. military personnel defines the facet 'Military rank', to categorize the ranks of the persons;
  3. cars defines the facet 'Color', to categorize the primary colors of the cars.

The following table lists some common facets:

For heritage objects:

Facet nameDescription
TypeThe types of heritage objects, e.g. 'Building', 'Painting'.
CreatorThe creators of heritage objects, e.g. 'Vincent van Gogh', 'Rembrandt'.
Made in centuryThe dates of creation of heritage objects grouped by century, e.g. '17th century', '18th century'.
Made in placeThe places of creation of heritage objects, e.g. 'Amsterdam', 'The Hague'.
PublisherThe heritage institutions that publish information about heritage objects, e.g. 'Rijksmuseum', 'National Archives'.

For persons:

Facet nameDescription
Place of birthThe places of birth of persons, e.g. 'Amsterdam', 'The Hague'.
OccupationThe occupations of persons, e.g. 'Blacksmith', 'Mayor'.
PublisherThe heritage institutions that publish information about persons, e.g. 'Rijksmuseum', 'National Archives'.

Data model

NameDescription
Root Facet CollectionA collection of facet collections.
Facet CollectionA collection of categorized values, pointing to facet pages containing the actual values.
Facet PageA subcollection of categorized values, part of a facet collection.
Facet TermA selectable option within a facet page, pointing to an entity.
EntityAn identifiable 'thing' relevant to heritage. See Entities.

The following entity-relationship diagram visualizes the data model:

notitie

To be discussed: replace the ER diagram with a class diagram to make the relationships clearer (e.g. inheritance).

Identification of facet items

notitie

To do: explain how facet items can be identified:

  • By ID. For example: the name 'Jan de Vries' can be ambiguous in the 'Creator' facet; there can be several persons with that name. If the data layer intends to resolve this, it should identify items by their ID (e.g. https://example.org/v1/entities/persons/1234), to make clear the item is about a specific person, regardless of the name of the person.
  • By name or label. For example: the name 'Jan de Vries' can be ambiguous in the 'Creator' facet. The data layer may decide to not resolve this: identification by ID could mean that several items with the same name appear in the facet list ('Jan de Vries', 'Jan de Vries', 'Jan de Vries'), each with an ID that a user in the presentation layer does not see and/or can interpret. In that case the data layer may identify items by their name, causing distinct persons with the same name to be grouped in one facet item ('Jan de Vries').

Endpoint: Retrieve a root facet collection

The endpoint retrieves the facet collections belonging to a heritage collection. The API MUST implement this endpoint if it supports facets.

This is a discovery endpoint: it allows presentation layers to identify the facet collections and their endpoint URIs.

HTTP request

GET /{version}/{collections}(/{...collections})/{collection}/{extensions}/{facets}

Path parameters

NameData typeCardinalityDescription
versionstring1The version of the API. Example: v1.
collectionsstring1The path identifier of the top root heritage collection. Example: collections.
...collectionsstring0 or moreThe path identifier(s) of further root heritage collections. Example: objects.
collectionstring1The path identifier of the heritage collection. Example: masterpieces.
extensionsstring1The path identifier of the extension collection. Example: extensions.
facetsstring1The path identifier of the root facet collection. Example: facets.

Query parameters

None.

Request body

None.

Response body

The response body MUST contain at least the following fields:

NameData typeCardinalityDescription
idstring1The identifier of the collection.
typestring1The type of the collection. It MUST be RootFacetCollection.
namestring1A short, human-readable name of the collection.
totalItemsnumber1The total number of facets in the collection.
itemsarray1A list of all facet collections. The API defines the order.
items[*]FacetCollection1A facet collection.
items[*].idstring1The identifier of the facet collection.
items[*].typestring1The type of the facet collection. It MUST be FacetCollection.
items[*].namestring1A short, human-readable name of the facet collection.
partOfExtensionCollection1The extension collection of which this extension is a part.
partOf.idstring1The identifier of the extension collection.
partOf.typestring1The type of the extension collection. It MUST be ExtensionCollection.

Example

An example request from a presentation layer:

GET /v1/collections/objects/extensions/facets HTTP/2
Host: example.org

The request indicates that the API should return the root facet collection of a heritage collection (objects).

An example of the response body of the API:

{
"id": "https://example.org/v1/collections/objects/extensions/facets",
"type": "RootFacetCollection",
"name": "Facets",
"totalItems": 2,
"items": [
{
"id": "https://example.org/v1/collections/objects/extensions/facets/centuries",
"type": "FacetCollection",
"name": "Made in century"
},
{
"id": "https://example.org/v1/collections/objects/extensions/facets/creators",
"type": "FacetCollection",
"name": "Creator"
}
],
"partOf": {
"id": "https://example.org/v1/collections/objects/extensions",
"type": "ExtensionCollection"
}
}

The response indicates that the API has two facet collections that are a part of the root collection: 'Made in century' and 'Creator'.

Endpoint: Retrieve a facet collection

The endpoint retrieves a facet collection. The API MUST implement this endpoint if it supports facets.

HTTP request

GET /{version}/{collections}(/{...collections})/{collection}/{extensions}/{facets}/{facet}

Path parameters

NameData typeCardinalityDescription
versionstring1The version of the API. Example: v1.
collectionsstring1The path identifier of the top root heritage collection. Example: collections.
...collectionsstring0 or moreThe path identifier(s) of further root heritage collections. Example: objects.
collectionstring1The path identifier of the heritage collection. Example: masterpieces.
extensionsstring1The path identifier of the extension collection. Example: extensions.
facetsstring1The path identifier of the root facet collection. Example: facets.
facetstring1The path identifier of the facet collection. Example: creators, centuries.

Query parameters

NameData typeCardinalityDescription
qstring0 or 1A keyword query for filtering the facet terms. Minimum length: defined by the data layer (e.g. 3 characters). Maximum length: defined by the API (e.g. 25 characters).
sizenumber0 or 1The maximum number of facet terms to retrieve. Minimum: 1. Default: 10. Maximum: defined by the API (e.g. 100).
orderBystring0 or 1The sorting order of the facet terms. One of count, value. Default: count:desc (most frequent term first). The API defines which value is used to sort by value (e.g. the name of an entity).
notitie

To do: add the query parameters representing the "search context" from the heritage collection (q and filter from endpoint Retrieve a page in a heritage collection).

Request body

None.

Response body

The response body MUST contain at least the following fields:

NameData typeCardinalityDescription
idstring1The identifier of the collection.
typestring1The type of the collection. It MUST be FacetCollection.
namestring1A short, human-readable name of the collection.
totalItemsnumber0 or 1The total number of facet terms in the collection. May be an estimate. Not set if it is too costly to calculate.
firstFacetPage0 or 1The first page in the collection. Not set if the collection is empty.
first.idstring1The identifier of the first page in the collection.
first.typestring1The type of the first page in the collection. It MUST be FacetPage.
lastFacetPage0 or 1The last page in the collection. Not set if the collection is empty or if the last page is unknown (e.g. in case of cursor pagination).
last.idstring1The identifier of the last page in the collection.
last.typestring1The type of the last page in the collection. It MUST be FacetPage.
partOfRootFacetCollection1The root facet collection of which this facet collection is a part.
partOf.idstring1The identifier of the root facet collection.
partOf.typestring1The type of the root facet collection. It MUST be RootFacetCollection.

Example

An example request from a presentation layer:

GET /v1/collections/objects/extensions/facets/creators HTTP/2
Host: example.org

The request indicates that the API should return a facet collection (creators) of a heritage collection (objects).

An example of the response body of the API:

{
"id": "https://example.org/v1/collections/objects/extensions/facets/creators",
"type": "FacetCollection",
"name": "Creator",
"totalItems": 195,
"first": {
"id": "https://example.org/v1/collections/objects/extensions/facets/creators?page=1",
"type": "FacetPage"
},
"last": {
"id": "https://example.org/v1/collections/objects/extensions/facets/creators?page=20",
"type": "FacetPage"
},
"partOf": {
"id": "https://example.org/v1/collections/objects/extensions/facets",
"type": "RootFacetCollection"
}
}

Endpoint: Retrieve a page in a facet collection

The endpoint retrieves a page in a facet collection. The API MUST implement this endpoint if it supports facets.

HTTP request

GET /{version}/{collections}(/{...collections})/{collection}/{extensions}/{facets}/{facet}?page={page}

Path parameters

NameData typeCardinalityDescription
versionstring1The version of the API. Example: v1.
collectionsstring1The path identifier of the top root heritage collection. Example: collections.
...collectionsstring0 or moreThe path identifier(s) of further root heritage collections. Example: objects.
collectionstring1The path identifier of the heritage collection. Example: masterpieces.
extensionsstring1The path identifier of the extension collection. Example: extensions.
facetsstring1The path identifier of the root facet collection. Example: facets.
facetstring1The path identifier of the facet collection. Example: creators, centuries.

Query parameters

NameData typeCardinalityDescription
pagestring1The identifier of the page: a page number or cursor, depending on the pagination strategy of the API.
qstring0 or 1A keyword query for filtering the facet terms. Minimum length: defined by the data layer (e.g. 3 characters). Maximum length: defined by the API (e.g. 25 characters).
sizenumber0 or 1The maximum number of facet terms to retrieve. Minimum: 1. Default: 10. Maximum: defined by the API (e.g. 100).
orderBystring0 or 1The sorting order of the facet terms. One of count, value. Default: count:desc (most frequent term first). The API defines which value is used to sort by value (e.g. the name of an entity).
notitie

To do: add the query parameters representing the "search context" from the heritage collection (q and filter from endpoint Retrieve a page in a heritage collection).

Request body

None.

Response body

The response body MUST contain at least the following fields:

NameData typeCardinalityDescription
idstring1The identifier of the current page.
typestring1The type of the page. It MUST be FacetPage.
namestring1A short, human-readable name of the page.
itemsarray1A list of facet terms.
items[*]FacetTerm1A facet term.
items[*].typestring1The type of the facet term. It MUST be FacetTerm.
items[*].countnumber1The number of occurrences of the value of the facet term.
items[*].valueEntity1The value of the facet term.
items[*].value.typestring1The type of the value of the facet term. It MUST be a type of Entity.
items[*].value.idstring1The identifier of the value of the facet term.
items[*].value.namestring1The name of the value of the facet term.
prevFacetPage0 or 1The previous page in the collection. Not set if there is no previous page.
prev.idstring1The identifier of the previous page in the collection.
prev.typestring1The type of the previous page in the collection. It MUST be FacetPage.
nextFacetPage0 or 1The next page in the collection. Not set if there is no next page.
next.idstring1The identifier of the next page in the collection.
next.typestring1The type of the next page in the collection. It MUST be FacetPage.
partOfFacetCollection1The collection of which this page is a part. See the response body of endpoint Retrieve a facet collection.

Example

An example request from a presentation layer:

GET /v1/collections/objects/extensions/facets/creators?page=3 HTTP/2
Host: example.org

The request indicates that the API should return page 3 in a facet collection (creators) of a heritage collection (objects).

An example of the response body of the API:

{
"id": "https://example.org/v1/collections/objects/extensions/facets/creators?page=3",
"type": "FacetPage",
"name": "Creator",
"items": [
{
"type": "FacetTerm",
"count": 12,
"value": {
"id": "https://example.org/v1/entities/persons/1234",
"type": "Person",
"name": "Arno Haag"
// Optionally: other fields...
}
},
{
"type": "FacetTerm",
"count": 8,
"value": {
"id": "https://example.org/v1/entities/persons/5678",
"type": "Person",
"name": "Hans de Haan"
// Optionally: other fields...
}
}
// Other items...
],
"prev": {
"id": "https://example.org/v1/collections/objects/extensions/facets/creators?page=2",
"type": "FacetPage"
},
"next": {
"id": "https://example.org/v1/collections/objects/extensions/facets/creators?page=4",
"type": "FacetPage"
},
"partOf": {
// Omitted for brevity — see the response body of endpoint
// "Retrieve a facet collection"
}
}