CYCLOPS (CCLP) API version v1
https://github.com/indexdata/mod-cyclops/
CYCLOPS (CCLP) API
API calls to interact with the various CCMS commands
Overview
This WSAPI provides a RESTish and FOLIO-idiomatic way of invoking the operations to be supported by the CCMS server, the data-management middleware at the heart of the CYCLOPS system. Based on section 2.3 (Commands) of the CCMS Documentation, the following commands will be supported, and will act on the specified kinds of object.
- 2.3.1.
add tag-- operates on sets (using tags and filters) - 2.3.2.
create set-- operates on sets - 2.3.3.
define filter-- operates on filters (using other filters) - 2.3.4.
define tag-- operates on tags - 2.3.5.
delete-- operates on sets (using filters and tags) - 2.3.6.
help-- (can be ignored) - 2.3.7.
insert-- operates on sets (using other sets, filters and tags) - 2.3.8.
remove tag-- operates on sets (using tags and filters) - 2.3.9.
retrieve-- operates on sets (using filters and tags) - 2.3.10.
show filters-- operates on filters - 2.3.11.
show sets-- operates on sets - 2.3.12.
show tags-- operates on tags
This gives us three kinds of object that we need to represent RESTfully, and one more implied object representing the set of tags associated with a set:
- tags (2 operations) at
/cyclops/tags - filters (2 operations) at
/cyclops/filters - sets (7 operations) at
/cyclops/setsand individual sets at/cyclops/sets/{setName}- tags applied to a set at
/cyclops/sets/{setName}/tag/{tagName}
- tags applied to a set at
The last of these paths is the most conceptually complex. The path /cyclops/sets/mike/tag/dino represents the resource "the subset of records within the set mike that are tagged with dino". POSTing to that resource can add or remove records to the subset by associating the tag with records in the wider set. (The path for this resource includes the currently redundant component /tag in case we need to extend the set API later on to address other kinds of object associated with sets.)
Implementation note. Operations on tags do not rely on any other kind of object. Operations on filters rely only on other filters. So the dependency graph is simple: we need to implement both tags and filters (in either order) before we can fully implement sets.
/cyclops
Tags that can be applied to records in a set
Return a list of all known tags
Create a new tag
get /cyclops/tags
Return a list of all known tags
HTTP status code 200
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A list of zero or more tags",
"type": "array",
"items": {
"type": "object",
"$ref": "tag-schema.json"
}
}
Example:
[
{
"name": "dino"
},
{
"name": "ptero"
},
{
"name": "croc"
}
]
post /cyclops/tags
Create a new tag
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A tag in a CYCLOPS system, used to mark objects within a set",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The short human-readable name of the tag"
}
},
"additionalProperties": false,
"required": [
"name"
]
}
Example:
{
"name": "dino"
}
HTTP status code 204
No content is returned.
Filters that can narrow down records within a set
Return a list of all known filters
Create a new filter
get /cyclops/filters
Return a list of all known filters
HTTP status code 200
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A list of zero or more tags",
"type": "array",
"items": {
"type": "object",
"$ref": "filter-schema.json"
}
}
Example:
[
{
"name": "jurassic",
"cond": "143100000 <= age AND age <= 205000000",
"template": "mesozoic"
},
{
"name": "cretaceous",
"cond": "66000000 <= age AND age <= 143100000",
"template": "mesozoic"
}
]
post /cyclops/filters
Create a new filter
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A filter in a CYCLOPS system, used to capture a filtering criterion",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The short human-readable name of the filter"
},
"cond": {
"type": "string",
"description": "An SQL-like WHERE condition"
},
"template": {
"type": "string",
"description": "Optionally, the name of another filter to duplicate"
}
},
"additionalProperties": false,
"required": [
"name",
"cond"
]
}
Example:
{
"name": "jurassic",
"cond": "143100000 <= age AND age <= 201400000",
"template": "mesozoic"
}
HTTP status code 204
No content is returned.
Sets of objects (books, films, etc.)
Return a list of the names of all known sets
Create a new set
get /cyclops/sets
Return a list of the names of all known sets
HTTP status code 200
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A list of zero or more sets",
"type": "array",
"items": {
"type": "object",
"$ref": "set-schema.json"
}
}
Example:
[
{
"name": "mike"
},
{
"name": "test"
},
{
"name": "uob"
}
]
post /cyclops/sets
Create a new set
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A set in a CYCLOPS system, representing a collections of objects",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The short human-readable name of the set"
}
},
"additionalProperties": false,
"required": [
"name"
]
}
Example:
{
"name": "mike"
}
HTTP status code 204
No content is returned.
Retrieve elements of a set
Delete a set
get /cyclops/sets/{setName}
Retrieve elements of a set
URI Parameters
- setName: required(string)
The name of the set to retrieve from, modify, delete or tag
Query Parameters
- fields: required(string)
Either * (for all fields) or a comma-separated list
- cond: (string)
An SQL-like WHERE condition
- filter: (string)
The name of a filter to apply to the set
- tag: (string)
The name of a tag to which to restrict the retrieved objects
- omitTag: (string)
The name of a tag by which to exclude objects from the retrieved
- sort: (string)
a comma-separated list of fields to sort the objects on. The default order is undefined if this is not specified
- offset: (number)
number of objects that will be skipped and not returned as part of the result. This can be useful for retrieving objects one page of data a time. Note that 'sort' is required whenever this is used
- limit: (string)
a maximum number of objects that will be returned
HTTP status code 200
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A response to a CYCLOPS retrieve command, containing values from some fields in a set of objects",
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Status of retrieveal, or 'error'"
},
"message": {
"type": "string",
"description": "Error message, only if status==error"
},
"fields": {
"type": "array",
"description": "Error message, only if status==error",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of a field included among the data rows"
}
},
"additionalProperties": false,
"required": [
"name"
]
}
},
"data": {
"type": "array",
"description": "List of returned data rows",
"items": {
"type": "object",
"properties": {
"values": {
"type": "array",
"description": "XXX An array of data values, belonging to the fields named in the 'fields' top-level element",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"values"
]
}
}
},
"additionalProperties": false,
"required": [
"status"
]
}
Example:
{
"status": "ok",
"message": "XXX This message should not exist, since status != 'error'",
"fields": [
{
"name": "id"
},
{
"name": "author"
},
{
"name": "title"
}
],
"data": [
{
"values": [
"123",
"J. R. R. Tolkien",
"The Lord of the Rings"
]
},
{
"values": [
"456",
"Douglas Adams",
"The Hitch-Hiker's Guide to the Galaxy"
]
}
]
}
add objects to a set
post /cyclops/sets/{setName}/add
add objects to a set
URI Parameters
- setName: required(string)
The name of the set to retrieve from, modify, delete or tag
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A request to add objects to a set",
"type": "object",
"properties": {
"from": {
"type": "string",
"description": "Name of the set from which records are to be added to this one"
},
"cond": {
"type": "string",
"description": "An SQL-like WHERE condition specifying the selection of records to be added"
},
"filter": {
"type": "string",
"description": "The name of a filter to be applied to selection of records to be added"
},
"tag": {
"type": "string",
"description": "A comma-separated list of the names of tags, specifying that only those selected records with any of the tags will be added"
},
"omitTag": {
"type": "string",
"description": "A comma-separated list of the names of tags, specifying that only those selected records without any of the tags will be be added"
},
"limit": {
"type": "string",
"description": "A maximum number of objects that will be added to the set"
}
},
"additionalProperties": false,
"required": [
"from"
]
}
Example:
{
"from": "mike",
"cond": "date >= \"2025-01-01\"",
"filter": "jurassic",
"tag": "dino,ptero",
"omitTag": "croc",
"limit": "200"
}
HTTP status code 204
No content is returned.
remove objects from a set
post /cyclops/sets/{setName}/remove
remove objects from a set
URI Parameters
- setName: required(string)
The name of the set to retrieve from, modify, delete or tag
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A request to remove objects from a set",
"type": "object",
"properties": {
"cond": {
"type": "string",
"description": "An SQL-like WHERE condition specifying the selection of records to be deleted"
},
"filter": {
"type": "string",
"description": "The name of a filter to be applied to selection of records to be deleted"
},
"tag": {
"type": "string",
"description": "A comma-separated list of the names of tags, specifying that only those selected records with any of the tags will be deleted"
},
"omitTag": {
"type": "string",
"description": "A comma-separated list of the names of tags, specifying that only those selected records without any of the tags will be deleted"
}
},
"additionalProperties": false
}
Example:
{
"cond": "date < \"2025-01-01\"",
"filter": "cretaceous",
"tag": "dino",
"omitTag": "ptero,croc"
}
HTTP status code 204
No content is returned.
add tag to, or remove tag from, objects within in a set
post /cyclops/sets/{setName}/tag/{tagName}
add tag to, or remove tag from, objects within in a set
URI Parameters
- setName: required(string)
The name of the set to retrieve from, modify, delete or tag
- tagName: required(string)
The name of the tag to add or remove to object within the set. The path
/cyclops/sets/mike/tag/dinorepresents the resource "the set of records that are tagged withdinoin the setmike.
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A request to add a tag to, or remove a tag from from, objects within a set",
"type": "object",
"properties": {
"op": {
"type": "string",
"description": "Operation to perform: add or remove",
"enum": ["add", "remove"]
},
"cond": {
"type": "string",
"description": "An SQL-like WHERE condition specifying the selection of records included in the operation"
},
"filter": {
"type": "string",
"description": "The name of a filter to be applied to selection of records included in the operation"
}
},
"additionalProperties": false,
"required": [
"op"
]
}
Examples:
add:
{
"op": "add",
"cond": "title LIKE \"%saur\"",
"filter": "jurassic"
}
remove:
{
"op": "remove",
"cond": "author LIKE \"%taylor%\"",
"filter": "cretaceous"
}
HTTP status code 204
No content is returned.
The projects in the system, in which collaborative collection management takes place
Return a brief list of all known projects
Create a new project
get /cyclops/projects
Return a brief list of all known projects
HTTP status code 200
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A list of zero or more projects",
"type": "array",
"items": {
"type": "object",
"$ref": "project-schema.json"
}
}
Example:
[
{
"id": 321,
"name": "Slavic studies",
"altName": "palci_slavic",
"action": {
"id": 123,
"name": "Purchase"
}
},
{
"id": 456,
"name": "Literature of North Korea",
"altName": "lit_nk",
"action": {
"id": 654,
"name": "Weed"
}
},
{
"id": 789,
"name": "Ukrainian Culture",
"altName": "ukr1",
"action": {
"id": 987,
"name": "Digitize"
}
}
]
post /cyclops/projects
Create a new project
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A single project in detail",
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier"
},
"name": {
"type": "string",
"description": "Human-reeadable name"
},
"altName": {
"type": "string",
"description": "Optional alternative name, e.g. a slug"
},
"action": {
"type": "object",
"description": "At the moment, self-documentation is all we can do: see CYCLOPS-12",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the action"
},
"name": {
"type": "string",
"description": "Human-readable name of the action"
}
},
"additionalProperties": false
},
"mouLink": {
"type": "string",
"format": "uri",
"description": "An optional link to a memorandom of understanding"
},
"funds": {
"type": "array",
"description": "A list of the project's funds which can be used to action spectres",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the fund"
},
"name": {
"type": "string",
"description": "Human-readable name of the fund"
}
},
"additionalProperties": false
}
},
"people": {
"type": "array",
"description": "The people associated with the project and their roles",
"items": {
"type": "object",
"description": "A single person associated with the project",
"required": [
"xid",
"role"
],
"properties": {
"xid": {
"type": "string",
"description": "An external identified, opaque to CCMS, of a user in the system that is communicating with CCMS, with user administation being handled by that system"
},
"role": {
"type": "string",
"description": "One of a small set of roles that a person have in a project (e.g. 'admin', 'editor', 'viewer')"
}
},
"additionalProperties": false
}
},
"locations": {
"type": "array",
"description": "The locations that can act as sources and destinations for the action associated with this project",
"items": {
"type": "object",
"description": "A single location used by the project",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the location"
},
"name": {
"type": "string",
"description": "Human-readable name of the location"
}
},
"additionalProperties": false
}
},
"tracks": {
"type": "array",
"description": "The tracks within the project that a given spectre can be associated with",
"items": {
"type": "object",
"description": "A singe track within the project",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the track"
},
"name": {
"type": "string",
"description": "Human-readable name of the track"
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false,
"required": [
"id",
"name",
"action"
]
}
Example:
{
"id": 321,
"name": "Slavic studies",
"altName": "palci_slavic",
"action": {
"id": 123,
"name": "Purchase"
},
"mouLink": "https://www.miketaylor.org.uk/dino/pubs/",
"funds": [
{
"id": 345,
"name": "PALCI cultural preservation"
},
{
"id": 456,
"name": "Coalition for Slavic literature"
}
],
"people": [
{
"xid": "p567",
"role": "Admin"
},
{
"xid": "p678",
"role": "`Visionary"
}
],
"locations": [
{
"id": 789,
"name": "Lehigh"
},
{
"id": 890,
"name": "NYU"
},
{
"id": 901,
"name": "CLOCKSS"
}
],
"tracks": [
{
"id": 12,
"name": "Offsite"
},
{
"id": 123,
"name": "Reserve"
},
{
"id": 234,
"name": "Stacks"
}
]
}
HTTP status code 204
No content is returned.
Fetch a full project
Delete a project
Modify a project
get /cyclops/projects/{id}
Fetch a full project
URI Parameters
- id: required(string)
HTTP status code 200
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A single project in detail",
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier"
},
"name": {
"type": "string",
"description": "Human-reeadable name"
},
"altName": {
"type": "string",
"description": "Optional alternative name, e.g. a slug"
},
"action": {
"type": "object",
"description": "At the moment, self-documentation is all we can do: see CYCLOPS-12",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the action"
},
"name": {
"type": "string",
"description": "Human-readable name of the action"
}
},
"additionalProperties": false
},
"mouLink": {
"type": "string",
"format": "uri",
"description": "An optional link to a memorandom of understanding"
},
"funds": {
"type": "array",
"description": "A list of the project's funds which can be used to action spectres",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the fund"
},
"name": {
"type": "string",
"description": "Human-readable name of the fund"
}
},
"additionalProperties": false
}
},
"people": {
"type": "array",
"description": "The people associated with the project and their roles",
"items": {
"type": "object",
"description": "A single person associated with the project",
"required": [
"xid",
"role"
],
"properties": {
"xid": {
"type": "string",
"description": "An external identified, opaque to CCMS, of a user in the system that is communicating with CCMS, with user administation being handled by that system"
},
"role": {
"type": "string",
"description": "One of a small set of roles that a person have in a project (e.g. 'admin', 'editor', 'viewer')"
}
},
"additionalProperties": false
}
},
"locations": {
"type": "array",
"description": "The locations that can act as sources and destinations for the action associated with this project",
"items": {
"type": "object",
"description": "A single location used by the project",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the location"
},
"name": {
"type": "string",
"description": "Human-readable name of the location"
}
},
"additionalProperties": false
}
},
"tracks": {
"type": "array",
"description": "The tracks within the project that a given spectre can be associated with",
"items": {
"type": "object",
"description": "A singe track within the project",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the track"
},
"name": {
"type": "string",
"description": "Human-readable name of the track"
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false,
"required": [
"id",
"name",
"action"
]
}
Example:
{
"id": 321,
"name": "Slavic studies",
"altName": "palci_slavic",
"action": {
"id": 123,
"name": "Purchase"
},
"mouLink": "https://www.miketaylor.org.uk/dino/pubs/",
"funds": [
{
"id": 345,
"name": "PALCI cultural preservation"
},
{
"id": 456,
"name": "Coalition for Slavic literature"
}
],
"people": [
{
"xid": "p567",
"role": "Admin"
},
{
"xid": "p678",
"role": "`Visionary"
}
],
"locations": [
{
"id": 789,
"name": "Lehigh"
},
{
"id": 890,
"name": "NYU"
},
{
"id": 901,
"name": "CLOCKSS"
}
],
"tracks": [
{
"id": 12,
"name": "Offsite"
},
{
"id": 123,
"name": "Reserve"
},
{
"id": 234,
"name": "Stacks"
}
]
}
put /cyclops/projects/{id}
Modify a project
URI Parameters
- id: required(string)
Body
Media type: application/json
Type:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A single project in detail",
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier"
},
"name": {
"type": "string",
"description": "Human-reeadable name"
},
"altName": {
"type": "string",
"description": "Optional alternative name, e.g. a slug"
},
"action": {
"type": "object",
"description": "At the moment, self-documentation is all we can do: see CYCLOPS-12",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the action"
},
"name": {
"type": "string",
"description": "Human-readable name of the action"
}
},
"additionalProperties": false
},
"mouLink": {
"type": "string",
"format": "uri",
"description": "An optional link to a memorandom of understanding"
},
"funds": {
"type": "array",
"description": "A list of the project's funds which can be used to action spectres",
"items": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the fund"
},
"name": {
"type": "string",
"description": "Human-readable name of the fund"
}
},
"additionalProperties": false
}
},
"people": {
"type": "array",
"description": "The people associated with the project and their roles",
"items": {
"type": "object",
"description": "A single person associated with the project",
"required": [
"xid",
"role"
],
"properties": {
"xid": {
"type": "string",
"description": "An external identified, opaque to CCMS, of a user in the system that is communicating with CCMS, with user administation being handled by that system"
},
"role": {
"type": "string",
"description": "One of a small set of roles that a person have in a project (e.g. 'admin', 'editor', 'viewer')"
}
},
"additionalProperties": false
}
},
"locations": {
"type": "array",
"description": "The locations that can act as sources and destinations for the action associated with this project",
"items": {
"type": "object",
"description": "A single location used by the project",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the location"
},
"name": {
"type": "string",
"description": "Human-readable name of the location"
}
},
"additionalProperties": false
}
},
"tracks": {
"type": "array",
"description": "The tracks within the project that a given spectre can be associated with",
"items": {
"type": "object",
"description": "A singe track within the project",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier of the track"
},
"name": {
"type": "string",
"description": "Human-readable name of the track"
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false,
"required": [
"id",
"name",
"action"
]
}
Example:
{
"id": 321,
"name": "Slavic studies",
"altName": "palci_slavic",
"action": {
"id": 123,
"name": "Purchase"
},
"mouLink": "https://www.miketaylor.org.uk/dino/pubs/",
"funds": [
{
"id": 345,
"name": "PALCI cultural preservation"
},
{
"id": 456,
"name": "Coalition for Slavic literature"
}
],
"people": [
{
"xid": "p567",
"role": "Admin"
},
{
"xid": "p678",
"role": "`Visionary"
}
],
"locations": [
{
"id": 789,
"name": "Lehigh"
},
{
"id": 890,
"name": "NYU"
},
{
"id": 901,
"name": "CLOCKSS"
}
],
"tracks": [
{
"id": 12,
"name": "Offsite"
},
{
"id": 123,
"name": "Reserve"
},
{
"id": 234,
"name": "Stacks"
}
]
}
HTTP status code 204
No content is returned.