Resource Server REST API Version 2

Using the Resource Server REST API Version 2

The following paragraphs give an overview of version 2 of the API and the basic concepts by example, while each section describes each method or operation in detail.

Version 2 of the Resource Server API adds support for newer types of stores like the distributed store type which uses a Cassandra database as storage. The behavior of these stores differs slightly from earlier store types which is why a new version of the resource server API was introduced. Except for the delete operation the Resource Server API URI’s have not changed much and simply contain v2 instead of v1. For the delete operation, this operation is now recursive and the condition that directories must be empty before they can be deleted is removed. The following is a full example (assuming localhost and port 13242): http://localhost:13242/resources/v2/data/customer-sets/

Some usage examples:

The Resource Server includes HTTP ETag and MD5 hashing support, but stores are not required to provide this (although most of them will). Specifications of ETag and Content-MD5:

The resource server also specifies the Server HTTP header with value resources/1.0. This is useful to check if (unexpected) results, such as HTTP status codes 404, were triggered by the expected service.

Note

Note that for the most part this version of the Resource Server API behaves in exactly the same way as version 1. This version of the API adds support for newer store types which no longer update the ETag of a directory if one of its descendant resources is altered. This API should only be used if both the sync-recursive and sync-snapshot features are supported by the client. See Listing resource stores for more information.

/resources/v2/data/{store-name}/{path}{resource-name}

PUT PUT method to add or update a resource, or create a directory.

Description

Examples with store named home:

  • /resources/v2/data/home/set007/contract.scd: Add a template contract.scd in directory set007.
  • /resources/v2/data/home/overview.xml: Add an XML file to the root of the store.
  • /resources/v2/data/home/set008/: Create a directory set008 to the root of the store.

Parameters

Name Located in Description Type
store-name path
String
path path
String
resource-name path
String

Responses

200 The resource is updated.
201 The resource or directory is created.
401 Invalid credentials or not authorized.
403 The operation is forbidden. For example, when trying to put a resource with the same name as an existing directory.
404 (Parent) path is not found. Note, directories in a path which do not exist are not automatically created. Directories need to be created individually instead.
412 Precondition failed: An HTTP If-Match precondition failed. The tracked ETag in the store was different than the one specified in the If-Match header.

GET Retrieve a resource, or a folder listing via HTTP GET.

Description

HTTP HEAD is also supported, in which only the response headers are returned. The HTTP response headers include ETag, Content-MD5 (not for folder listings), Last-Modified and the Resource Server specific extension Last-Modified-Millis, which is last modified expressed in Unix time. Examples with store named home:

  • /resources/v2/data/home/set007/contract.scd: Get the template contract.scd in directory set007.
  • /resources/v2/data/home/overview.xml: Get an XML file from the root of the store.
  • /resources/v2/data/home/set008/: Get a listing of directory set008.

Parameters

Name Located in Description Type
store-name path
String
path path
String
resource-name path
String

Responses

200 The resource or folder listing is successfully retrieved.

Examples

<resources>
  <resource name="C0012.scd" tag="e2a20dfa-0c64-42b4-922a-d6bb0c09ede4" last-modified="2016-07-08T09:32:01.842Z" />
  <resource name="C0019.scd" tag="10462975-345f-47f9-8af9-1b91e6447afc" last-modified="2016-07-08T09:32:01.842Z" deleted="true" />
  <resource name="data" tag="077193d1-d1b1-4051-b7eb-5d271c0cab1f" last-modified="2016-07-08T09:32:01.842Z" directory="true" />
  <resource name="deprecated.xml" tag="104193d1-e1b2-4251-b7eb-1c91e6442afd" last-modified="2016-07-08T09:32:01.842Z" />
<resources>

Each resource element has the following attributes:

  • name: The name of the resource.
  • tag: The unique tag of the resource (the tracked HTTP ETag value for that resource).
  • deleted: Whether this is a (recently) deleted resource or not. Default is false.
  • directory: Whether the resource is a directory or not. Default is false.

Note

Stores only keep track of the deleted state of a resource for a certain amount of time, after which the resource is no longer marked as deleted. In this case they are no longer part of directory listings. Some store implementations do not track ETag values or deleted state. ETag values of ancestors are no longer required to change when a change occurs on a descendant resource.

204 No content. The resource is known to be deleted.
303 A directory was requested, but the path did not end with a slash '/'. The redirect is returned.
304 Not Modified. An HTTP If-None-Match precondition matched, indicating the resource did not change. In this case the resource is not returend. Other headers are also omitted.
400 Bad request. The reason of the bad request is stated as a message in text/plain.
401 Invalid credentials or not authorized.
404 The resource is not found. If the resource is known to be deleted, status code 4O4 is returned with response body "deleted" and ETag header set.

DELETE Delete method to recursively delete a resource.

Description

Examples with store named home:

  • /resources/v2/data/home/set007/contract.scd: Delete template contract.scd in directory set007.
  • /resources/v2/data/home/overview.xml: Delete the XML file from the root of the store.
  • /resources/v2/data/home/set008/: Delete the directory set008 and all its contents in the root of the store.

Responses

200 The resource or empty directory is deleted.
404 The resource or its parent directory can not be found.
412 Precondition failed: An HTTP If-Match precondition failed. The tracked ETag in the store was different that the one specified in the If-Match header.
401 Invalid credentials or not authorized.

/resources/v2/stores

GET Get method to retrieve a listing of available resource stores and their properties.

Responses

200 The resource store listing is successfully retrieved.

Examples

<stores>
  <store name="default-store" type="havail">
    <database-settings/>
      <store-features>
        <feature>sync-recursive</feature>
        <feature>sync</feature>
      </store-features>
      <store-settings>
        <setting>
          <name>filesystem-location</name>
          <value>/Users/twouters/scriptura/home/test/scriptura-0.0/data/default-store</value>
        </setting>
        <setting>
          <name>database-lock-timeout</name>
          <value>3600000</value>
        </setting>
        <setting>
          <name>database-transaction-retries</name>
          <value>10</value>
        </setting>
        <setting>
          <name>keep-deleted</name>
          <value>90</value>
        </setting>
        <setting>
          <name>database-connection-pool-size</name>
          <value>10</value>
        </setting>
        <setting>
          <name>database-driver</name>
          <value>org.postgresql.Driver</value>
        </setting>
        <setting>
          <name>database-dialect</name>
          <value>org.hibernate.dialect.PostgreSQLDialect</value>
        </setting>
        <setting>
          <name>filesystem-temp</name>
          <value>/Users/twouters/scriptura/home/test/scriptura-0.0/data/tmp</value>
        </setting>
        <setting>
          <name>database-connection-url</name>
          <value>jdbc:postgresql://localhost:5432/test</value>
        </setting>
        <setting>
          <name>database-password</name>
          <value></value>
        </setting>
        <setting> 
          <name>database-username</name>
          <value>test</value>
        </setting>
     </store-settings>
  </store>
</stores>

Each store element has the following attributes:

  • name: The name of the resource.
  • tag: The unique tag of the resource (the tracked HTTP ETag value for that resource).
  • deleted: Whether this is a (recently) deleted resource or not. Default is false.
  • directory: Whether the resource is a directory or not. Default is false.

The store-features element lists the features supported by a store and can be used by clients to determine how they should interact with the store. The following is a list of available features:

  • sync: Indicates whether the store supports the ability for clients to sync its contents.
  • sync-recursive: Indicates that the store supports the recursive sync type. Stores with this feature guarantee that the ETag of a directory changes if any resource below it is created, updated or deleted. This allows clients to recursively check their local data against the server and skip directories for which the ETag has not changed.
  • sync-snapshot: Indicates that the store supports the snapshot sync type. Stores with this feature will not change the ETag of a directory if any resource below it is created, updated or deleted. Clients that want to sync with stores that support this feature should retrieve a full listing for the path they want to sync by specifying the recursive query parameter when retrieving a directory listing.
400 Bad request. The reason of the bad request is stated as a message in text/plain.
401 Invalid credentials or not authorized.

POST POST method to add a new resource store to the configuration.

Responses

201 The resource store was successfully added to the configuration.
400 Bad request. The reason of the bad request is stated as a message in text/plain.
401 Invalid credentials or not authorized.

/resources/v2/stores/{store-name}

GET GET method to retrieve the configuration of a resource store.

Responses

200 The resource store configuration is successfully retrieved.
400 Bad request. The reason of the bad request is stated as a message in text/plain.
401 Invalid credentials or not authorized.

PUT PUT method to update the configuration of a resource store.

Responses

201 The resource store configuration is updated.
400 Bad request. The reason of the bad request is stated as a message in text/plain.
401 Invalid credentials or not authorized.

DELETE DELETE method to remove a resource store from the configuration.

Responses

200 The resource store configuration was successfully removed.
400 Bad request. The reason of the bad request is stated as a message in text/plain.
401 Invalid credentials or not authorized.

/resources/v2/poll

GET Long running GET operation to monitor for changes on the Resource Server stores.

Responses

200 The body contains a listing of change events

Examples

Change events is a plaintext resource that contains events separated by newlines that have occurred on the stores. The structure of most events is as follows (the text between braces is replaced by an actual value):

CHANGE {event ID} {IDR URI} {operation} {previous ETag} {new ETag} {type}
  • {event ID} an event ID, this will be unique within the same store.
  • {IDR Location} the IDR URI of the change. This URI thus contains the store and path of the resource that changed.
  • {operation} the operation that occurred can be one of the following: modify or delete.
  • {previous ETag} the previous ETAG of the resource, can be empty.
  • {new ETag} the new ETAG of the resource.
  • {type} the type of the resource, can be empty.

Useful client applications that use events are:

  • Monitor certain stores and paths for changes, and act upon this.
  • To implement a mirror of the resource store or a subtree of a store. By replaying the events on its local copy it remains in sync with the remote. This removes the need for a complex and resource intensive synchronization algorithm.

To implement a client that monitors for changes on the resource server, perform the following steps.

  • The client makes an initial request without query parameter.
  • The server responds with the current event status of all its stores. The client is required to maintain a mapping from a store it is interested in to that store’s most recent event.
  • The client is now able to send requests and may fill in query parameters based on the mapping from store to event that has been created in the previous step. Upon receiving this request from the client, the server responds with one of the following response codes:

    • Status 200 when new events occur or have occurred since the provided events.

    • The server will reply with a status 204 if no events occurred within 30 seconds after the connection was made.

    • If the server no longer knows the provided event for a provided store it sends back a reset. This may happen as the server only keeps events for a limited amount of time.

      RESET {store name} {event id}

    This message tells the client to reset its algorithm for this store and restart from the specified event.

    Note

    This means that the client might need to perform extra work to make sure that the resources are up to date. This can be done by using, for instance, a recursive listing to check that the client’s state is still in sync with that of the server.

  • Based on the server’s response, the client must update the mapping it keeps from stores to events and send the next request.
204 There are no modifications.
401 Invalid credentials or not authorized.