Expressing Capabilities in RAPID Schema Definition Language (RSDL)
RAPID uses a Schema Definition Language (RSDL) to describe the structure of a REST service. Developers can be annotate their schema model with capabilities in order to describe the capabilities of their service.
- Annotating Model Elements
- Annotating Paths
Annotating Model Elements
Model elements are the service, operations, types, and properties defined in in an RSDL Schema.
Capabilities applied to model elements determine the set of paths and capabilities implemented by the service. The developer can generate a set of paths and capabilities from the annotated model to explore or further refine the supported functionality.
Capabilities for a model element are specified in curly braces following the model element definition. Omitting a capability within the curly braces means that capability is not supported. If no curly braces follow the model element, a default set of capabilities is assumed.
Support for reading data
A top level singleton or single-valued navigation property can be annotated with the READ
capability to show that it supports reading.
service {
company: Company { READ }
}
States that the path GET /company
is supported.
Applying the READ
capability to a top-level collection or collection valued navigation property states that individual members of the collection can be read using their key value.
service {
competitors: [Company] { READ }
}
type Company
{
key stockSymbol: String
...
}
States that the path GET /competitors/{stockSymbol}
is supported.
Read Options
The READ
capability can be further refined to specify the specific read capabilities that are supported. If no curly braces follow the READ
capability then a default set of capabilities is assumed. If empty curly braces follow the READ
capability then the value can be read, but none of the read options are supported.
Expand Option
The expand
option within the READ
capability specifies that navigation properties within the referenced type can be expanded.
service {
company: Company { READ { expand } }
}
The expand
option alone means that all navigation properties within the referenced type can be expanded. So, for example, the user can specify GET /company?$expand=employees
.
The expand
option may be followed by a list of individual navigation properties that can be expanded.
service {
company: Company { READ { expand { employees } } }
}
Means that only the employees navigation property can be expanded.
Nested Expand Options
The expand
option followed by an empty set of curly braces means that no properties can be expanded.
Collection-valued navigation properties can include nested expand expand, filter, orderBy, top/skip and count options, as appropriate.
In the example:
service {
company: Company { READ { expand { employees { top, skip, count, filter, orderby } } } }
}
top
, skip
, count
, filter
, and orderby
query options are supported when expanding employees from company:
GET /company?expand=employees(top=10;skip=1;count=true;filter=lastName eq 'Jetson';orderby=firstName)
Expand options can be applied to all navigation properties not otherwise specified using the *
service {
company: Company { READ { expand { * { top, skip, count, filter, orderby } } } }
}
top
, skip
, count
, filter
, and orderby
query options are supported when expanding all navigation properties from company.
If no curly braces follow a collection-valued navigation property, then top, skip, count, filter, and orderby are all assumed to be supported.
Additionally, if no curly braces follow a navigation property or *
, then it is assumed that expand
supports nested expands according to the capabilities of each navigation property of the target type, recursively.
If the navigation property or *
is suffixed by empty curly braces, then no expand options are supported when expanding the property.
Listing Collections
A top level collection can be annotated with the LIST
capability to show that it supports listing members.
service {
competitors: [Company] { LIST }
}
States that the path GET /competitors
is supported.
Similarly, a collection-valued navigation property can be annotated with the same capability:
service {
company: Company { READ }
competitors: [Company] { LIST, READ }
}
type Company
{
key stockSymbol: String
name: String
incorporated: Date
employees: [Employee] { LIST, READ }
}
The LIST
capability on competitors
means that the path GET /competitors
is supported.
The LIST
capability on employees
, along with the READ
capability on competitors
, means that the path GET /competitors/employees
is supported.
The LIST
capability on employees
, together with the READ
capability on company
, means that the path GET /company/{stockSymbol}/employees
is supported.
If there are no curly braces following a top-level collection or collection-valued navigation property within a type, it is assumed to support LIST
and READ
, as well as CREATE
, UPDATE
, and DELETE
.
List Options
The LIST
capability can be followed by a set of options that specify what capabilities the service supports when enumerating the collection.
LIST options include expand, filter, orderBy, top and skip, and count. If no options are supported, it is assumed that expand, filter, orderby, top, skip, and count are all supported when listing the collection. If an empty curly brace follows the LIST capability, it means that no list options are supported.
Filter Option
The filter
option specifies that a filter can be applied when listing the collection.
service {
competitors: [Company] { LIST { filter }, READ }
}
Specifies that the filter
query option can be used when listing competitors.
The filter
option may be followed by a list of individual navigation properties that can be filtered, optionally followed by a filter option
.
service {
competitors: [Company] { LIST { filter { name {stringComp} } } }
}
The competitors
collection can be filtered by name using the string comparison operators.
If no curly braces follow the filter
option, then the filterable
capability, if present on a property, is used to determine whether or not that property can be filtered upon. If filter
is followed by empty curly braces, then the collection does not support filtering on any properties.
Filterable capability
Individual properties of the collection type may be annotated with the filterable
capability to show that they can be used when filtering a collection of that type.
type Company
{
key stockSymbol: String { filterable }
name: String { filterable }
incorporated: Date { filterable }
employees: [Employee] { LIST { filter }, READ }
}
Specifies that filterable collections of companies can be filtered on stockSymbol, name, and incorporated.
Filter Operations
The filterable
capability can include a filter operation to specify the filter operators that can be applied when filtering by the property:
name: String { filterable { stringComp } }
Possible values for filter operations are as follows:
Property Type | filter operation | supported filter operators |
---|---|---|
any primitive | none | not filterable |
any primitive | eq | eq |
any primitive | comp | eq , gt , ge , lt , le |
string | string | eq , startswith , endswith , contains |
string | stringComp | eq , gt , ge , lt , le , startswith , endswith , contains |
Properties that do not have a filterable
capability, or that have a filterable
capability with no specified filter option, are assumed to be filterable in collections that support filtering using the filter operators appropriate to their type.
OrderBy Option
The orderby
option within the LIST
capability specifies that an orderby can be applied when listing the collection.
service {
competitors: [Company] { LIST { filter, orderby }, READ }
}
Specifies that the orderby
query option can be used when listing competitors.
The orderby
option may be followed by a list of individual properties that can be ordered, optionally followed by a filter option
.
service {
competitors: [Company] { LIST { orderby { name {asc, desc} } } }
}
The competitors collection can be ordered by name in ascending or descending order.
If no curly braces follow the orderby
option, then the orderability
capability, if present on a property, is used to determine whether or not that property can be ordered by. If orderby
is followed by empty curly braces, then the collection does not support ordering on any properties.
Orderable capability
Individual properties of the collection type may be annotated with the orderable
capability to show that they can be used when ordering a collection of that type.
type Company
{
key stockSymbol: String { orderable }
name: String { orderable }
incorporated: Date { orderable }
employees: [Employee] { LIST { filter, orderby }, READ }
}
Orderable collections of Company
can be ordered on stockSymbol
, name
, and incorporated
.
The orderable
capability can include the set of orderby options to specify whether the property can be ordered ascending, descending, or both.
name: String { orderable { asc, desc} }
The name
property can be ordered by ascending (asc
) or descending (desc
).
Primitive properties that do not have an orderable
capability, or that have a orderable
capability without specifying asc
or desc
, are assumed to be orderable in ascending or descending order.
Top and Skip Options
The top
and skip
option within the LIST
capability specify that top
and skip
query options can be used when listing the collection.
service {
competitors: [Company] { LIST { top, skip }, READ }
}
The top
and skip
query option can be used when listing competitors.
Count Option
The count
option within the LIST
capability specify that the count query option can be used when listing the collection.
service {
competitors: [Company] { LIST { count }, READ }
}
The count
query option can be used when listing competitors.
Support For Modifying Data
Capabilities can be applied to top-level collections and collection-valued navigation properties to specify whether they support POST
, PATCH
, PUT
, or DELETE
operations.
If no capabilities are applied to a top-level collection, or to a collection-valued navigation property, it is assumed to support POST
, PATCH
, and DELETE
, as well as GET
, but not PUT
.
Create Support
The CREATE
capability can be applied to a collection of navigation values to state that members can be inserted into the collection.
service {
competitors: [Company] { CREATE }
}
type Company
{
key stockSymbol: String
employees: [Employee] { CREATE }
}
States that the paths POST /competitors
and POST /competitors/{stockSymbol}/employees
are supported.
Create Options
The CREATE
capability can be followed by the expand
option to specify that the expand
query option can be applied to the POST
request in order to include related resources when returning the created item.
service {
competitors: [Company] { CREATE { expand { employees } } }
}
States that the path POST /competitors?expand=employees
is supported to return the new competitor along with related employees.
Update Support
The UPDATE
capability can be applied to a navigation property to state that the property is updatable.
service {
company: Company { UPDATE }
}
States that the path PATCH /company
is supported.
The UPDATE
capability can also be applied to an entity set or collection-valued navigation property to state that individual members of the collection can be updated.
service {
competitors: [Company] { UPDATE }
}
type Company
{
key stockSymbol: String
employees: [Employee] { UPDATE }
}
States that the paths PATCH /competitors/{stockSymbol}
and PATCH /competitors/{stockSymbol}/employees/{id}
are supported.
Update Options
The UPDATE
capability can be followed by the expand
option to specify that the expand
query option can be applied to the PATCH
request in order to include related resources when returning the updated item.
service {
company: Company { UPDATE { expand { employees } } }
}
States that the path PATCH /company?expand=employees
is supported to return the related employees along with the updated competitor.
Replace Support
The REPLACE
capability can be applied to a navigation property to state that the property can be replaced.
service {
company: Company { REPLACE }
}
States that the path PUT /company
is supported.
The REPLACE
capability can be applied to an entity set or collection-valued navigation property to state that individual members of the collection can be replaced.
service {
competitors: [Company] { REPLACE }
}
type Company
{
key stockSymbol: String
employees: [Employee] { REPLACE }
}
States that the paths States that the path PUT /competitors/{stockSymbol}
and
PUT /competitors{stockSymbol}/employees/{id}
are supported.
Replace Options
The REPLACE
capability can be followed by the expand
option to specify that the expand
query option can be applied the PUT
request in order to include related resources when returning the replaced item.
service {
company: Company { REPLACE { expand { employees } } }
}
States that the path PUT /company?expand=employees
is supported to return the related employees along with the competitor.
Delete Support
The DELETE
capability can be applied to a navigation property to state that the property can be deleted.
service {
company: Company { DELETE {} }
}
States that the path DELETE /company
is supported.
The DELETE
capability can also be applied to an entity set or collection-valued navigation property to state that individual members of the collection can be deleted.
service {
competitors: [Company] { DELETE{} }
}
type Company
{
key stockSymbol: String
employees: [Employee] { DELETE{} }
}
States that the paths DELETE /competitors/{stockSymbol}
and DELETE /competitors/{stockSymbol}/employees/{id}
are supported.
Delete options
The DELETE
capability does not support any delete options and must be followed by empty braces {}
to denote that no query options are supported.
Operation Support
Operations that return a single result can be followed by expand
to specify that the expand
query option can be applied the request in order to include related resources when returning the result.
service {
topCompany() : Company { expand { employees } }
}
type Company
{
key stockSymbol: String
employees: [Employee]
}
States that the path GET /topCompany?expand=employees
is supported to return the related employees along with the top company.
In addition to expand
, operations that return a collection can be followed by any of the LIST
capability options to specify filter
, orderby
, top
, skip
, and count
support.
service {
topCompanies( num: Integer ) : [Company] { filter, orderby, top, skip, count, expand }
}
States that query options filter
, orderby
, top
, skip
, count
, and expand
are all supported when calling topCompanies
.
Default Capabilities
Not applying capabilities to a model element means that you support the default capabilities for that element, as defined in the following table:
Model Element | Default Capabilities |
---|---|
Top-level collection or collection-valued navigation property | LIST, READ, CREATE, UPDATE, DELETE |
Singleton or single-valued navigation property | READ |
Annotating Paths
todo...