Monday, 25 July 2011

REST and role-based data models

Despite the popularity of REST approaches, there is still no standard mechanism for automatically generating url patterns appropriate for a database. The early implementations from Microsoft had a very complex url syntax, and the later MVC3 approaches simply expect programmers to create routing URLs.
There is not even any agreed way of deciding whether a data value should be given as an attribute or a child element of a given entity. Many data modelling systems allow a distinction between data values and attributes, and this can help. Let us suppose that the data model system is extended by adding a small set of metadata flags to indicate which tables are entities and which columns are attributes or properties.
Then the following modest proposal is offered as a natural url model for a REST service:
All data segments are URLencoded so that SQL identifiers never need to be enclosed in double quotes. Matching rules are applied in the order given, but can be disambiguated using the optional $ prefixes. White space is significant (e.g. the spaces in the rules below must be a single space, and the commas should not have adjacent spaces).

http://host:port/database/role{/Selector}{/Processing}

Selector matches
[$table ]id
[$procedure ]id[(string{,string}]
[$where ]id=string
[$select ]id{,id}
[$key ]string
Appending another selector is used to restrict a list of data to match a given primary key value or named column values, or to navigate to another list by following a foreign key, or supply the current result as the parameters of a named procedure, function, or method.

Processing matches:
distinct
ascending id{,id}
descending id{,id}
skip Int_string
count Int_string

For example with an obvious data model, GET http://Sales/Sales/Orders/1234 returns a single row from the Orders table, while http://Sales/Sales/Orders/1234/OrderItem returns a list of rows from the OrderItem table, and http://Sales/Sales/Orders/1234/CUST/Customer returns the row from the Customer table.
A URL can be used to GET a single item, a list of rows or single items, PUT an update to a single items, POST a new item to a list, or DELETE a single row.
For example, PUT http://Sales/Sales/Orders/1234/DeliveryDate with posted data of 2011-07-20 will update the DeliveryDate cell in a row of the Orders table.
POST http://Sales/Sales/Orders will create a new row in the Orders table: the posted data should contain the XML version of the row. In all cases the new primary key value will be contained in the Http response.

No comments:

Post a Comment