Broadcast on Broadcast off
The Documentation for Project Zero has moved. Please update your bookmarks to: http://www.projectzero.org/documentation/

Table of
Contents...
Hide

Project Zero Developer’s Guide

Concepts and components
Basic concepts overview
Event processing
Writing Java handlers
Writing Groovy handlers
Firing events
Global Context
Global Context reference
Application directory layout
Virtualized directories
Assemble
PHP
Features and configuration
Configuration
Debugging
Dependencies
Packaging
Application classpath
Logging and tracing
RESTful resources
RESTful documentation
File serving
Response rendering
Validators and validation
HTTP error handling
Calling a remote resource
Using the Connection API
Sending an email using EmailConnection
Configuring destinations
Configuring protocols
Configuring connection handlers
Creating a connection handler
Creating a custom protocol transport
Simple logging connection handlers
Protocol reference
Client programming with Dojo
Runtime options
Deployment modifications
HTTP configuration
SSL configuration
Proxy configuration
Extending the CLI
Security considerations
Authentication
OpenID authentication
Extending security
Security tokens
CSRF prevention support
Extending token support
Leveraging TAI
User service
File based user service
LDAP user service
Extending user service
Security Utilities
Leveraging XOREncoder
Extensions
Atom support
RSS support
JSON support
XMLEncoder
REST to SOAP extension
URIUtils
Developer Web tools
Database setup tools
Configuring data access
Common query patterns
Advanced query patterns
Update patterns
Local database transactions
Extending data access
Configuration vendor differences
PHP data access
Resource model
Configuring ZRM
Resource model declaration
Programmatic model API
HTTP REST API
A ZRM mini tutorial
Active content filtering support
Default filters
Custom filters
Runtime management
Management commands
Zero socket opener
Other extension modules
Amazon E-commerce service
Flickr service
WeatherZero forecast service
Wikipedia service
Reference
Zero command line interface
JavaDoc - Public API
JavaDoc - Public SPI
JavaDoc - All Classes

 

Resource model HTTP access

This example assumes the following persons model has been declared in /app/models/persons.groovy:

fields = [
    firstname: [type: 'CharField'],
    birthdate: [type: 'DateField'],
]

Enabling HTTP access

The HTTP API has many symmetries to the programmatic model API and allows HTTP REST access to models collections and members with very little coding. The HTTP API is not enabled by default but requires you to provide a resource event handler in the /app/resources directory. In its simplest form, the application REH delegates requests to a ZRM-provided resource event handler.

A resource event handler for the persons model located in /app/resources/persons.groovy only needs to contain:

ZRM.delegate()

The ZRM resource event handler provides default data access functionality with HTTP for the data defined in the /app/model file. The remainder of this section describes that default functionality.

Reading collections

The Project Zero resource model programmatic model API introduced the concept of a model's collection, Member instances and collection filtering. ZRM's HTTP API maps HTTP requests to invocations on the programmatic Model API, providing access to the same collection and member through easy to learn (and construct) URIs.

ZRM follows common REST idioms. Namely, you can use the HTTP GET command for a full or filtered a model's collection and POST member instances into the collection. You can also learn more about Reading and writing model collection member instances.

The HTTP GET URI syntax for addressing model collections is shown in the following example:

<urlPrefix>/<collectionName>[?<queryParameters>]

The following examples are valid URIs for the persons model:

http://localhost/resources/persons
Unfiltered collection of members
http://localhost/resources/persons?firstname__startswith=S
Filtered collection of members where all firstname values start with 'S'

Collection paging

Just as the Model API allows for specifying slice, or subset, of the overall collection, the HTTP API allows you to indicate a page range. This is done by defining the start and count parameters in the URI as follows:

http://localhost/resources/persons?start=100&count=199
Unfiltered collection of members from 101 to 200
http://localhost/resources/persons?firstname_contains=rand&start=5&count=5
Filtered collection of members that contain 'rand' and from 6 to 10

Note: Collection paging uses =0=-based indexing. For example, the first member in the collection is indexed at 0 and the 10th at 9.

If the data slice specified does not have a complete "page", the returned members are as expected. For example, if there are 7 members in a given collection and the first request is for start=0&count=5 then items 1 through 5 are returned. If the second request is made for start=5&count=5 then items 6 and 7 are returned.

Note: Specifying ordering in the following section changes the members in specified page ranges.

You can optionally specify both start and count. One or both must exist in order to obtain a slice of the results. The lack of both parameters means the results is*not* paged. However, if count is missing, the results start at the specified start and return to the end of the collection. Likewise, if start is missing, the results start at the beginning of the collection and return the number of members specified by count.

Collection ordering

As illustrated in the URIs in the previous example, you can order collections results in your HTTP GET requests. By default, HTTP collection requests for the Atom representation are sorted by members' updated value in descending order. Conversely, JSON collection representations are not sorted, or rather, or sorted from oldest to more recently created.

The order_by value syntax for the URL is based on the ZRM API syntax which is defined in the "Programmatic API" section. Ascending order is the default. To indicated descending order, prefix - before the field name as show in the previous URI examples.

http://localhost/resources/persons?order_by=birthdate
Unfiltered collection of members sorted youngest to oldest
http://localhost/resources/persons?id__lt=100&order_by=-birthdate,name
Filtered collection of members with id less than 100, sorted first from oldest to youngest and then by name from A to Z

Collection rendering

At present, collection data can be represented in either JSON or the Atom syndication format. The desired representation can be specified in the Accept header of the HTTP GET request by specifying the associated MIME type. The values application/json and application/atom+xml render JSON and Atom, respectively, to the response.

An alternative mechanism is provided for requesting a specific representation by using the URL query parameter format_as. Valid values for this parameter are json and atom.

http://localhost/resources/persons?format_as=atom
Collection of members with representation returned as Atom.
http://localhost/resources/persons?format_as=json
Collection of members with representation returned as JSON.

tip The default format is JSON if the Accept header is not specified and the URI parameter is not provided.

JSON representation

ZRM uses the JSONArray and JSONObject implementations of zero.core to render the JSON representation. A model collection is a JSONArray of JSONObject. Each JSONObject contains the member instance of the model in the collection. For example, the persons model when the collection contains two members rendered in JSON is:

[
    {
   "firstname": "Jane",
   "birthdate": "1973-12-03"
    },
    {
   "firstname": "John",
   "birthdate": "1982-04-29"
    }
]

Atom format

The default Atom representation of a model's collection is as you would expect: an Atom feed containing an Atom entry for each member. The default serialization of the model instance member data is put in the atom:content section as key, value pairs in XOXO format. The remaining required atom elements are set to default values as shown in the following example of the default Atom representation of the same data in the JSON example that was shown above:

<feed xmlns="http://www.w3.org/2005/Atom">       
    <title>Title of Type persons Feed</title>                      
    <link href="http://localhost/resources/persons"/>            
    <updated>2003-12-13T18:30:02Z</updated>        
    <id>"http://localhost/resources/persons"</id>                                                        
    <entry>                                         
      <title>Title of persons 2</title>                         
      <link href="http://localhost/resources/persons/1"/>       
      <id>"http://localhost/resources/persons/1"</id>          
      <updated>2003-12-13T18:30:02Z</updated>   
      <author>Author of persons 1</author>                      
      <content type="xhtml">                         
        <div xmlns="http://www.w3.org/1999.xhtml">    
        <ol class='xoxo'><li>persons<dl>             
          <dt>firstname</dt><dd>Jane</dd>           
          <dt>birthdate</dt><dd>1973-12-03</dd>              
        </dl></li></ol>                                
        </div>                                        
      </content>                                      
    </entry>                                         
    <entry>                                            
      <title>Title of persons 2</title>                            
      <link href="http://localhost/resources/persons/2"/>        
      <id>"http://localhost/resources/persons/2"</id>            
      <updated>2003-12-13T18:30:02Z</updated>         
      <author>Author of persons 2</author>                     
      <content type="xhtml">                         
        <div xmlns="http://www.w3.org/1999.xhtml">    
        <ol class='xoxo'><li>persons<dl>               
          <dt>firstname</dt><dd>John</dd>            
          <dt>birthdate</dt><dd>1982-04-29</dd>              
        </dl></li></ol>                                
        </div>                                        
      </content>                                    
    </entry>                                          
</feed>       

Customizing the Atom representation

You can use the model declarations in the /app/models folder to customize the rendering of an Atom entry. You can define a set of keywords as a Groovy closure using the calculated_fields definition. With these named calculated_fields, you can define the values to be set in selected elements in the atom entry.

Adding the following definition to the persons model's /app/model/persons.groovy file and using the same member instance data in the previous example results in the following Atom entry:

calculated_fields = [
     atom_feed_title: { "My Feed Title"}
     atom_author_name: { member -> member.lastname },
     atom_title: { member -> member.firstname },
     atom_summary: { member -> "All about ${member.firstname}." },
]

<feed xmlns="http://www.w3.org/2005/Atom">       
    <title>My Feed Title</title>                      
     <link href="http://localhost/resources/persons"/>            
     <updated>2003-12-13T18:30:02Z</updated>        
     <id>"http://localhost/resources/persons"</id>                                                        
     <entry>                                         
        <title>Jane</title>                         
        <link href="http://localhost/resources/persons/1"/>       
        <id>"http://localhost/resources/persons/1"</id>  
        <summary>All about Jane.</summary>        
        <updated>2003-12-13T18:30:02Z</updated>   
        <author>Doe</author>                      
        <content type="xhtml">                         
            <div xmlns="http://www.w3.org/1999.xhtml">    
             <ol class='xoxo'><li>persons<dl> 
                <dt>firstname</dt><dd>Jane</dd>           
                <dt>lastname</dt><dd>Doe</dd>              
             </dl></li></ol>                                
            </div>                                        
        </content>                                      
     </entry> 
</feed>  

Collection filtering

You can filter collection by limiting the set of members to be returned based on one or more filter conditions. A set of filter parameters is enabled for each collection type based on the data model specified. Some examples were given earlier in this document. Here are some further examples:

http://localhost:8081/resources/persons?firstname__contains=Jo
Filtered collection where member instances' firstname field contains 'Jo'
http://localhost:8081/resources/persons?firstname__contains=Jo&birthdate__day=25,
Filtered collection where member instances' firstname field contains 'Jo' and birthdate falls on the 25th of the any month.

The valid filter conditions and corresponding parameter syntax for the URL is based on the programmatic model API filtering syntax of the Project Zero resource model. This is defined in the Filter conditions section under the Programmatic model API topic. Note that the URL syntax uses equal signs (=) to set the filter parameters and ampersands (&) to combine the filter conditions.

Reading and writing collection members

Member rendering and parsing

Incoming data used for creating and updating members must be either in JSON or Atom representations. The Content-Type header of the HTTP request determines how the data is parsed. The MIME types application/json and application/atom+xml parse JSON and Atom, respectively. If neither is specified, the default parser is JSON.

Creating a member

New collection members can be created by making an HTTP POST request to the collection URI of the model with the member representation as shown in the following example:

POST /resources/persons
Content-Type: application/json
{
   "firstname": "Bill",
   "birthdate": "1976-09-25"
}

Retrieving a member

An individual collection member can be retrieved by issuing a GET command on the collection URI with the member ID as a parameter, as shown in the following example:

GET resources/persons/1

Updating a member

A collection member can be updated by issuing a PUT command with the member representation on the collection URI, as shown in the following example:

PUT /resources/persons/1
Content-Type: application/json
{
   "firstname": "Janie",
   "birthdate": "1973-12-04"
}

Deleting a member

A collection member can be deleted by issuing a DELETE command with the member ID on the collection URI, as shown in the following example:

DELETE /resources/persons/1

Reading type collection metadata

By default, the metadata of a collection can be retrieved through HTTP as a JSON representation. This is done using the following URI convention:

/resources/types[/typesId]

For example, assume that the following resource model is defined:

// /app/models/persons.groovy
fields = [
    first_name:[type:'CharField', required: true],
    birth_date:[type:'DateField'],
    is_child:[type: 'BooleanField'],
]

With this model in place, the following HTTP JSON response is returned:

GET /resources/types/persons

{
  "type":"person",
  "fields": {
    "id": {
       "type":"AutoField",
       "required":false,
       "editable":true,
       "primary_key":true,
       "max_length":null
    },
    "updated": {
       "type":"DateTimeField",
       "required":false,
       "editable":true,
       "primary_key":false,
       "max_length":null
    },
    "birth_date": {
       "type":"DateField",
       "required":true,
       "editable":true,
       "primary_key":false,
       "max_length":null
    },
    "first_name": {
       "type":"CharField",
       "required":true,
       "editable":true,
       "primary_key":false,
       "max_length":50
       },
    "is_child": {
       "type":"BooleanField",
       "required":true,
       "editable":true,
       "primary_key":false,
       "max_length":null
    }
  }
}

By specifying the named resource model /resources/types/persons only the JSON object for the persons type is returned. You can obtain a list of all resource model definitions by making an HTTP GET request to /resources/types.

NOTE: At present, additional metadata fields are returned for each field definition. This is subject to change.

r22 - 09 Feb 2008 - 18:27:31 - paynel
Syndicate this site RSS ATOM
Copyright 2007 © IBM Corporation | Privacy | Terms of Use | About this site