Chapter 8. Control Parameters

Table of Contents

Filtering Collection with cayenneExp
Ordering Collection with sort / dir
Pagination with start / limit
Shaping Collection Entities with include / exclude

Control parameters, usually passed as URL keys, apply to the Collection Document and let the server to provide a single generic endpoint per entity, while still allowing the client to shape up the response Collection to its liking. These parameters are normally used with GET, however POST/PUT can also return a Collection Document, so many of the parameters are also applicable when modifying the data.

Filtering Collection with cayenneExp

A conditional expression that is used to filter the response objects. Expression String should follow the format understood by Cayenne (hence the name - "cayenneExp"). The root for the property paths is the request entity (unless "cayenneExp" is used within a relationship "include", in which case the root is that related entity).

Example 1: Filtering on a single property.

cayenneExp=vhost='linkrest.org'

Example 2: Filtering using outer join (the "+" sign is Cayenne notation for outer).

cayenneExp=articles+ = null

Example 3: Filtering with parameters using positional bindings.

cayenneExp=["articles.body like $b","%LinkRest%"]

Example 4: Filtering with parameters using named bindings.

cayenneExp={ "exp" : "articles.body like $b", "params": {"b":"%LinkRest%"}}

Ordering Collection with sort / dir

Example 1: Sort on a single property.

sort=vhost

Example 2: Sort descending on a property.

sort=id&dir=DESC

Example 3: Same as 2, but sort is a JSON object.

sort={"property":"vhost","direction":"DESC"}

Example 4: Multiple sortings as a single JSON structure.

sort=[{"property":"name"},"property":"vhost","direction":"DESC"}]

Pagination with start / limit

These two parameters are used together to request from the server a range of objects for a potentially huge collection. They allow to implement efficient data pagination on the client.

"start" is an offset within the "data" array. All the objects below this offset are discarded from the collection. Default "start" is 0.

"limit" is a maximum number of objects in the collection "data". Default is infinity (no limit).

"limit" is applied after "start". So for a collection with a total of 10 objects, ?start=2&limit=5 would result in objects 2..6 returned from the server. Returned Collection "total" would still be 10.

Shaping Collection Entities with include / exclude

Model entities may have "simple" properties (attributes) and properties that point to related entities (relationships). By default Collection Document contains entity representation that includes its "id", all of its attributes, and none of the relationships. "include" and "exclude" parameters allow the client to request a specific subset of entity properties, including related entities. Some examples are given below, showing include/exclude parameters and resulting entity contents.

Example 1: Include default properties (all entity attributes) minus "vhost" attribute.

exclude=vhost

{ "id" : 45, "name" : "LinkRest Site" } 

Example 2: Exclude all properties, but "id".

include=id

{ "id" : 45 } 

Example 3: Multiple includes, one of them points to attributes of related entity.

include=id&include=articles.title

{
   "id" : 45,
   "articles" : [
      { "title" : "LinkRest Includes" }, 
      { "title" : "Other Tech News" },
      { "title" : "Introducing LinkRest" }
   ]
}

Example 4: Advanced include. Include specification can itself be a JSON object and contain "cayenneExp", "sort", "start" and "limit" keys shaping up a collection of related objects for each root object.

include={"path":"articles","cayenneExp":"title like '%LinkRest%'","sort":"title"}&include=articles.title

{
   "id":45,
   "articles" : [
      { "title" : "Introducing LinkRest" },
      { "title" : "LinkRest Includes" }
   ]
}

Example 5: Related objects as a map. Here we'll map article bodies by title.

include={"path":"articles","mapBy":"title"}&include=articles.body

{
   "articles" : {
      "Introducing LinkRest" : { "body" : "LinkRest is a .." },
      "LinkRest Includes" : { "body" : "Includes are .." }
   }
}