Personal tools

Laszlo on REST

From OpenLaszlo

Contents

Ruby REST Proposed API (in progress)

Schema

All Resources

URL 
OPTIONS http://#{url}/*
Returns 
Payload containing a description of the resources available
Payload 
An array of JSON objects as described immediately below

Available resources for a resource type

URL 
OPTIONS http://#{url}/#{resource_name}
Returns 
Payload containing a list of resources available and the publicly available associations for the resource
Payload Example
{
  associations: [
    { has_many: "employee" }, { belongs_to: "company" }
  ],
  queryable_via: [ "ids", "names", "phone_numbers" ],
  resources: [ "/1", "/2", "/3", "/4" ]
}

Methods available for a resource

URL 
OPTIONS http://#{url}/#{resource_name}/#{resource_id}
Returns 
List of available methods (or 404 if the resource does not exist)
Payload Example
{
  methods: [ "GET", "PUT", "DELETE" ]
}

Read

URL 
GET http://#{url}/#{resource_name}/#{resource_id}
Returns 
An appropriate representation of the resource (based on the Accept header)
URL 
GET http://#{url}/#{resource_name}?#{name}=#{comma_separated_values} (e.g. http://example.com/foos?ids=1,2,7)
Returns 
An appropriate representation of the resources matching the request
Note 
Servers need only expose ids=, but might also expose other queryable properties. If additional properties are allowed, they should be described in the Schema documents.

Create

URL 
POST http://#{url}/#{resource_name}
Headers 
Mime-Type for the resource description
Body 
An appropriate representation of the resource(s) to be created
Status Code Returned 
201 (Created) or 204 (No Content)
Response Header 
Location: New URI that can be used to READ the created resource(s) (see above). If multiple resources are created, the server should return a URL that contains a query-string that represents the group of resources to retrieve.
Payload Example
{
  attributes: { foo: "bar", baz: "bat" }
}

Update

URL 
PUT /Same as for READ, but only ids= supported for multiple resources/
Headers 
Mime-Type for the resource description
Body 
An appropriate representation of the resource(s) to be updated. If updating multiple resources, the descriptions must include the identifier for the resource for each description
Status Code Returned 
204 (No Content) if the PUT did not modify the URI for the resource; 301 (Moved permanently) if it did
Response Header 
Location: New URI if a 301 is returned
Payload 
Same as Create

Delete

URL 
DELETE /Same as for READ/
Status Code Returned 
204 (No Content) if successful

Note

Read, Update, and Delete return a 404 (Not Found) if the resource is not available on the server. If the request is made via a query-string and at least one item is found, the response will indicate success, and the body will include a list of items in the comma-separated-list that were not found. If none of the items in the query-string is found, the server will return a 404 (Not Found).


Laszlo on Rails API

This section documents the current (Rails 1) REST API.

Schema

Request 
'http://localhost:3000/ + this.modelName + '/schema/'
Example 
http://localhost:3000/maxs/schema
Payload
<element name="max">
<column type="text" name="firstname"/>
<column type="text" name="lastname"/>
<column type="integer" name="id"/>
<column type="text" name="email"/>
</element>

Read

Request
 'http://localhost:3000/' + this.modelName + '/page/' + o
 /contacts/records # renders an XML serialization of all the records
 /contacts/records/1-10 # serializes records with ids 1 through 10
 /contacts/records/1,5,10
 /contacts/records/1-10,20-30
 /contacts/pages/1-10 # serializes the first 10 records
Example
http://localhost:3000/maxs/records
Payload
<records count="2" totalcount="2">
<max firstname="max" lastname="carlson" id="2" email="blah"/>
<max firstname="max" lastname="carlson" id="3" email="blah"/>
</records>

Create

Request 
'http://localhost:3000/' + this.modelName + '/create/' + o
Example 
http://localhost:3000/maxs/create/firstname=max&lastname=carlson&email=blah
Payload
<create>2</create>

Update

Request 
'http://localhost:3000/' + this.modelName + '/update/' + o
Example 
http://localhost:3000/maxs/update/id=1&firstname=oliver&lastname=steele&email=blah
Payload
<update>1</update>

Delete

Request 
'http://localhost:3000/' + this.modelName + '/delete/' + o
Example 
http://localhost:3000/maxs/delete/1
Payload
<deleted id="1"/>

Notes

We want to use the default Rails 2 REST support where possible.

URI formatting

URLs should look like this for Rails 2 REST:

'http://' this.hostName + '/' + this.modelName + '/' + recordid + '?' + params

With the operation being implicit based on the HTTP method used.

For example, POSTing to http://locahost:3000/contacts/15?foo=bar (with the ? bits in the post body) would update record ID 15 by changing the 'foo' field.

Flash limitations

Flash only supports POST and GET so we need to explicitly tell Rails when we want to DELETE and PUT. Apparently, this can be dealt with by passing a magic '_method' parameter in the post body - see here: http://marstonstudio.com/index.php/2007/07/12/answer-on-rest-xml-and-flash/

Flash can't access the body of non-2xx response and can’t reliably read the response code or headers. This limits the utility of a purely REST approach. http://livedocs.adobe.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002875.html talks about the ability to read the status code in Flash 8 and later, but http://blogs.adobe.com/kiwi/2006/07/making_http_calls_in_actionscr.html points out other headers can't be read. Therefore, the Location: header for a 301: response can't be read.