UserPreferences

PaceSimplifyCollections2


Abstract

Simplify everything by introducing a simple search via URI template.

Status

Open (JoeGregorio)

Rationale

Introducing Search into the APP, and mandating that the results of the search requests be Atom Feeds allows the APP to be vastly simplified. This Pace does that simplification.

The Pace drops the Introspection document, leaving that for another specification.

The Pace adds Search Resources which implement A9 OpenSearch style parametrized search URIs. The search parameters are restricted to date ranges and index ranges. The current spec has date queries but they are buried in a header and are not extensible. The use of the 'next' attribute in the current spec almost forces the server to implement indexes which I found out when implementing. Again, the search interface just takes that functionality, puts it in a common mechanism with date queries, and allows for future extensions.

Proposal

Add the following definitions to Section 3.

Entry Resource - A resource whose representation is an Atom Entry.

Generic Resource - A resource whose representation is not an Atom Entry, such as an image (image/png).

The Atom Publishing Protocol operates on collections of Web resources.
All collections support the same basic interactions, as do the resources 
within the collections. The patterns of interaction are based on the common HTTP verbs.

    * GET is used to retrieve a representation of a resource or perform a read-only query.
    * POST is used to create a new, dynamically-named resource.
    * PUT is used to update a known resource.
    * DELETE is used to remove a resource.

4.1 Editable Resources

An Editable resource is a resouce that 
can be edited via the HTTP methods
GET, PUT and DELETE.

4.1.1 Read

Client                                   Server 
  |                                           |
  |  1.) GET or HEAD to Editable Resource URI |     
  |------------------------------------------>|     
  |                                           |     
  |  2.) 200 OK                               |    
  |<------------------------------------------|
  |                                           |


   1. The client sends a GET (or HEAD) request to the member's URI.
   2. The server responds with the represenation of the resource.

4.1.2 Update

Client                                     Server
  |                                           |
  |  1.) PUT to Editable Resource URI         |     
  |------------------------------------------>|     
  |                                           |     
  |  2.) 200 OK                               |    
  |<------------------------------------------|
        

   1. The client PUTs an updated representation to the member's URI.
   2. The server MAY respond with an updated representation of the member's new state.

4.1.3 Delete

Client                                     Server 
  |                                           |
  |  1.) DELETE to Editable Resource URI      |     
  |------------------------------------------>|     
  |                                           |     
  |  2.) 200 Ok                               |    
  |<------------------------------------------|     
  |                                           |
        

   1. The client sends a DELETE request to the member's URI.
   2. The server responds with successful status code.



4.2 Collections

The APP groups Editable Resources with representations in
Atom Entry Format into "Collections", which are analogous to 
the "folders" or "directories" found in many file systems. 
All Editable Resources that are members of a Collection 
have representations as Atom Entries. 

4.3 Introspection

To discover the capabilities of a Collection Resource, the client
GET's the Collection Document from the Collection.

Client                            Server 
  |                                  |     
  |  1.) GET to Collection Resource  |     
  |--------------------------------->|     
  |                                  |     
  |  2.) Collection Document         |     
  |<---------------------------------|     
  |                                  |
          

   1. The client sends a GET request to the Collection Resource.
   2. The server responds with an Collection Document containing 
     a description of the capabilities of the collection. The content 
     of this document can vary based on aspects of the client request, 
     including, but not limited to, authentication credentials.


4.4 Listing

Clients can request a listing of the collection's membership. 
Enumerating the Editable Resources that are members of a collection
is done using one of the Search Resources listing in the 
Introspection Document. The Search Resource returns Atom Feed Documents
with all the Entries that match the search criteria.

Client                      Server 
|                                |     
|  1.) GET to Search Resource    |     
|------------------------------->|     
|                                |     
|  2.) 200 OK, Atom Feed Doc     |    
|<-------------------------------|     
|                                |
          

   1. The client sends a GET request to the Collection's URI.
   2. The server responds with an Atom Feed Document 
      containing a full or partial listing of the collection's membership.


4.5 Authoring

A client can add new Entries to a Collection by sending a 
request to the collection; other changes are accomplished by sending 
HTTP requests to the Editable Member resources.

4.5.1 Create

Client                      Server 
|                                |     
|  1.) POST to Collection URI    |     
|------------------------------->|     
|                                |     
|  2.) 201 Created @ Location    |    
|<-------------------------------|     
|                                |
        

   1. The client sends an Atom Entry Document to the server via 
      HTTP POST. The Request URI is that of the Collection Resource.
   2. The server responds with a response of "201 Created" and a 
      "Location" header containing the URI of the newly-created resource.

4.5.2 Editing Member Resources

Members of Collections are Editable Resources
and are edited following the patterns in Section 4.1.

Section 4.5 "Success and Failure" Remains unchanged. (Except it is now Section 4.6)

Section 5 Collection Document

The Collection Document describes the capabilites of a Collection, the
types of Entries that it will accept, the types of searching it 
supports, etc. The Collection Document has the media-type 'application/atomcoll+xml', see Section 11

<collection xmlns="http://purl.org/atom/app">
   <member-type>entry</member-type>
   <search-template>http://example.org/{index}</search-template>
   <search-template>http://example.org/d/{daterange}</search-template>
</collection>


5.1 The 'app:collection' Element

The "collection" element is the document element of an Collection Document, 
acting as a container for service data associated with one Collection.

appService =
   element app:collection {
      ( appMemberType+
        appSearchTemplate
        & anyElement* )
   }

The following child elements are defined by this specification:

    * app:collection elements MAY contain any number of app:member-type elements.
    * app:collection elements MAY contain any number of app:search-template elements.

5.2 The 'app:member-type' Element

The 'member-type' element element contains information elements about the types
of Entries that the Collection may contain.

appMemberType =
   element app:member-type {
      appTypeValue
   }


The value of appTypeValue MUST be a string that is non-empty, and matches either the 
"isegment-nz-nc" or the "IRI" production in [RFC3987]. Note that use of a relative 
reference other than a simple name is not allowed. If a name is given, implementations 
MUST consider the link relation type to be equivalent to the same name registered within 
the IANA Registry of Link Relations Section 12, and thus the IRI that would be obtained 
by appending the value of the rel attribute to the string "http://www.iana.org/assignments/entrytype/". 

The value of appTypeValue specifies constraints
on the Entries that may appear in the Collection. The app:collection element
may have multiple app:member-type elements. An Entry POSTed to a Collection
MUST meet the constaints of at least one of the app:member-type constraints. 
It MAY meet more than one, but the mimimum requirement is at least one.

This specification defines two initial values for app:member-type IANA registry:

 "entry" - The Collection is an Entry Collection as defined in Section 6.

 "generic" - The Collection is a Generic Collection as defined in Section 7.

5.3 The 'app:search-template' Element

The 'app:search-template' element describes searching capabilites.

The content of the app:search-template element is a URI Template
of a Search Resource (See Section 6). Every search resource, whose URI is determined
by filling in the variables in a URI Template, MUST return an Atom Feed
as it's representation.  The Atom Feed MUST be filled with entries
that match the search critera.
Section 6 Search Resources

Search resources are resources that are identified by URI Templates.
They MUST return Atom Feed Documents as their representation, and unless 
otherwise stated the entries in the document must be ordered by their atom:updated property,
with the most recently updated entries coming first in the document. Clients
MUST NOT assume that the entry returned in the feed is a full representation
of a member resource. If the entry is an Editable Resource then the client should 
perform a GET on the member resource before editing.


Section 6.1 URI Templates

URI Templates are a mechanisms for allowing queries using HTTP URIs.
By itself a URI Template is not a valid URI. Instead there are multiple parameters
embedded in the URI and distinguised by closing braces. For example:

   htpp://example.org/blog/edit/{index}

or 

   http://example.org/blog/{daterange} 


The value of each app:search-template element is a template of the URI for a Search Resource.

1. The variables in the template are enclosed in unescaped braces '{' and '}'.
1. With the exception of the variable names and their enclosing braces, the template URI MUST be properly escaped.
1. The character encoding of the template URI, and of the URI after the template is filled in, MUST be utf-8.

Each URI template has one or more variables that must be substituted with the values of
the named variables to construct a valid URI.

1. Substitute the brace-delimited variable, and the surrounding braces, for the 
   desired value of that variable, ensuring that the value is also properly percent-encoded utf-8.

For example, given the URI template:

   htpp://example.org/blog/edit/{index}

and if the client wants the first 15 entries in the collection it would substitute '1-15' for {index} giving:

   htpp://example.org/blog/edit/1-15

Note that the template can appear at any place in the URI template:

   URI Template                            |  Value of index  | Expanded URI
   ----------------------------------------+------------------+--------------------------------------
   http://example.org/{index}/search       |   3-27           | http://example.org/3-27/search
   http://example.org/search?index={index} |   3-27           | http://example.org/search?index=3-27

Section 6.2 URI Template Variables

This specification defines two variables that can be used in app:search-template values, called
URI Templates. Other specifications MAY define new variables used in URI templates. An
Introspection Document MUST contain at least two app:search-template elements. One of those
URI Templates MUST contain only a single variable whose name is {index}. The other 
of the two required URI Templates MUST contain only a single variable whose name is
{daterange}. There may be any number of app:search-template elements that contain
URI Templates that do not match the two required by this specification.


Section 6.2.1 URI Template Variable 'index'

A URI Template with the variable 'index' allows querying 
for entries in a collection using their index
when ordered by their 'updated' property.


The value of the index variable should be a pair of indices separated by a dash character; 
either index may be optionally omitted, in which case the range is understood 
as stretching to infinity on that end.

   index-specifier = [indexnum] "-" [indexnum]

The response to such a search request MUST be an Atom Feed where all the entries fall within 
the requested range. The request range is considered a closed set, that is, 
if an entry matches one end of the range exactly it MUST be included in the response. 
If no members fall in the requested range, the server MUST respond with an
Atom Feed containing no entries.


Section 6.2.2 URI Template Variable 'daterange'


A URI Template with the variable 'daterange' allows querying 
for entries in a collection using their 'updated' property.

The value of the 'daterange' variable should be a pair of iso formatted dates
separated by a dash character; 
either index may be optionally omitted, in which case the range is understood 
as stretching to infinity on that end.

   daterange-specifier = [iso-date] "/" [iso-date]

The 'iso-date' MUST conform to the 
"date-time" production in [RFC3339]. In addition, an uppercase "T" character 
MUST be used to separate date and time, and an uppercase "Z" character 
MUST be present in the absence of a numeric time zone offset.

The response to such a search request MUST be an Atom Feed where all the entries fall within 
the requested range. The request range is considered a closed set, that is, 
if an entry matches one end of the range exactly it MUST be included in the response. 
If no members fall in the requested range, the server MUST respond with an
Atom Feed containing no entries.
Section 7 Collection Resources

This specification defines two HTTP methods for use with collection resources: GET and POST.

7.1 GET

Get to a Collection Resource returns a Collection Document.

7.2 POST

In addition to GET, a Collection Resource also accepts POST requests. The client POSTs a representation of the desired resource to the Collection Resource. Note that some collections only allow members of a specific media-type and a POST MAY generate a response with a status code of 415 ("Unsupported Media Type").

In the case of a successful creation, the status code MUST be 201 ("Created").

Example Request, Create a resource in a collection.

In addition to GET, a Collection Resource also accepts POST requests. The client POSTs a
representation of the desired resource to the Collection Resource. Note that some collections may impose
constraints on the media-types that are created in a Collection.

In the case of a successful creation, the status code MUST be 201 ("Created").

Example Request, Create a resource in a collection.

POST /collection HTTP/1.1
Host: example.org
User-Agent: Cosimo/1.0
Accept: application/atom+xml
Content-Type: application/atom+xml
Content-Length: nnnn

<entry ....
...</entry>

                  
Here, the client is adding a new Entry to a collection. 

Example Response, resource created successfully.

HTTP/1.1 201 Created
Date: Fri, 25 Mar 2005 17:17:11 GMT
Content-Length: nnnn 
Content-Type: application/atom+xml; charset="utf-8"
Location: http://example.org/edit/first-post.atom

<?xml version="1.0" encoding="UTF-8"?>
<entry ...
</entry>

Every successful POST must return an Atom Entry in the response
that describes the newly created resource. In addition a
Location: header MUST be returned with the URI of the newly
created resource. 

Move Sections 5 of -04 here and rename as section 8.


Section 9 Generic Collection

Generic Collections are Collections that do not have uniform restrictions on the representations of the member resources.
9.1 Editing Generic Resources

Member resources are edited by sending HTTP requests to an individual resource's URI. 
Servers can determine the processing necessary to interpret a request by examining 
the request's HTTP method and 'Content-Type' header.

    Processing Client Requests
        GET     PUT     DELETE  POST
No Body         Read    x       Delete  x 
Any Body        x       Update  x       x 

When a query resource returns an Atom Feed enumerting 
the contents of a Generic Collection, all the 
Entries MUST have an atom:content element with 
a src attribute.

9.1 Title: Header

The POST to a Generic Collection Resource MAY contain a Title: header 
that indicates the clients suggested title for the resource. 
The server MAY ignore the Title: header or modify the requested title
to suit local conventions. 

  Title     = "Title" ":" text

Section 10 Member Resources

Section 10.1 Atom Entry Extensions

   This specification adds three new values to the Registry of 
   Link Relations. 

   The value of 'collection' signifies that the IRI in the value
   of the href is the Collection that this Entry belongs to. 

   The value of 'edit' signifies that the IRI in the value of the href attribute 
   identifies the resource that is used to edit the entry. That is, 
   it is the URI of the Entry as an Editable Resource.

   The value of 'srcedit' signifies that the IRI in the value of the href attribute identifies
   the resource that is used to edit the resource pointed to by 
   the 'src' attribute of the atom:content element. That is, it is the 
   URI of the atom:content@src as an Editable Resource.

   If the "srcedit" attribute is not given, it's value defaults to the "src" attribute
   of the content element.
 
   If the "srcedit" link is present, and it's value is an empty string, 
   then there is no URI that can be treated in the way such a value would be treated.

   Clients SHOULD use the "srcedit" value to manipulate the resource within the context 
   of the APP itself. Clients SHOULD prefer the "atom:content@src" value in any other context. 
   For example, if the resource is an image, a client may replace the image data using 
   a PUT on the "srcedit" value, and may even display a preview of the image by fetching 
   the "srcedit" URI. But when creating a public, read-only reference to the same image 
   resource, the client should use the "atom:content@src" value. 

Section 11 Examples

Section 11.1 Simple Create 
  
   Here is an example of creating a simple entry. In this example the
   client begins with only the URI of the Collection Resource, which is:

   http://example.org/app/

   The Entry that we wish to use to create a new resource with is:

   <?xml version="1.0" encoding="utf-8"?>
   <entry xmlns="http://www.w3.org/2005/Atom">
     <title>Atom-Powered Robots Run Amok</title>
     <updated>2003-12-13T18:30:02Z</updated>
     <summary>Some text.</summary>
     <content type="xhtml" xml:lang="en" 
         xml:base="http://example.org/">
        <div xmlns="http://www.w3.org/1999/xhtml">
           <p><i>Film at eleven.</i></p>
        </div>
     </content>   
   </entry>

   As you can see this Entry has a atom:content@type of 'xhtml'.
   First the client retrieves the Collection Document finds 
   out if the Collection can support this type of Entry.
   To retrieve the Collection Document it does a GET on
   the Collection Resource URI:

   GET /app/ HTTP/1.1
   Host: example.org
   User-Agent: Agent/1.0
   Accept: application/atomcoll+xml

   The Collection returns a representation the enumerates
   it's capabilities.

   HTTP/1.1 200 OK
   Date: Fri, 25 Mar 2005 17:15:33 GMT
   Last-Modified: Mon, 04 Oct 2004 18:31:45 GMT
   ETag: "2b3f6-a4-5b572640"
   Content-Type: application/atomcoll+xml; charset="utf-8"

   <?xml version="1.0" encoding="utf-8"?>
   <collection xmlns="http://purl.org/atom/app/">
      <member-type>text</member-type>
      <member-type>html</member-type>
      <member-type>xhtml</member-type> 
      <search-template>http://example.org/si/{index}</search-template>
      <search-template>http://example.org/bydate.cgi?{daterange}</search-template>
   </collection>

   The client finds an app:member-type element with a value of 'xhtml' so it
   knows that the Collection can indeed support the type of Entry it 
   is trying to create. The client POSTs the Entry to the Collection
   Resource URI:

   POST /app/ HTTP/1.1
   Host: example.org
   User-Agent: Cosimo/1.0
   Accept: application/atom+xml
   Content-Type: application/atom+xml
   Content-Length: nnnn

   <?xml version="1.0" encoding="utf-8"?>
   <entry xmlns="http://www.w3.org/2005/Atom">
     <title>Atom-Powered Robots Run Amok</title>
     <updated>2003-12-13T18:30:02Z</updated>
     <summary>Some text.</summary>
     <content type="xhtml" xml:lang="en" 
         xml:base="http://example.org/">
        <div xmlns="http://www.w3.org/1999/xhtml">
           <p><i>Film at eleven.</i></p>
        </div>
     </content>   
   </entry>

   If the resource is created successfully the response might be:

   HTTP/1.1 201 Created
   Date: Fri, 25 Mar 2005 17:17:11 GMT
   Content-Length: 0 
   Location: http://example.org/app/876

   Note that the Location: header gives the URI
   of the newly created member resource. 
Section 11.2 Resynchronization

   Here is an example of a client requesting all the Entries that have changed 
   since the last time the client synchronized with the server. The last time
   the client resynchronized from the server was 2003-12-13T18:30:02Z. The client
   wishes to get all the entries that have been updated since that time. The server 
   returns the following representation for it's Collection Resource:

   <?xml version="1.0" encoding="utf-8"?>
   <collection xmlns="http://purl.org/atom/app/">
      <member-type>entry</member-type>
      <search-template>http://example.org/si/{index}</search-template>
      <search-template>http://example.org/bydate.cgi?{daterange}</search-template>
   </collection>

   We are guaranteed to find at least one 'search-template' that allows us to search
   by the 'updated' time. That URI in this case is:

     http://example.org/bydate.cgi?{daterange}

   We expand the URI Template with our search criteria, which is a query 
   for all entries modified from 2003-12-13T18:30:02Z to now. The URI
   of that Search Resource is:

     http://example.org/bydate.cgi?/2003-12-13T18:30:02Z

   Remember that the first date in the date range is left empty if
   we want all entries modified until now. The response will be an Atom
   Feed of all the Entries that meet our criteria:

   HTTP/1.1 200 OK
   Date: Fri, 25 Mar 2005 17:15:33 GMT
   Last-Modified: Sun, 28 Aug 2005 18:31:45 GMT
   ETag: "23094-2349239-29348"
   Content-Type: application/atom+xml; charset="utf-8"

   <?xml version="1.0" encoding="utf-8"?>
   <feed xmlns="http://www.w3.org/2005/Atom">

     <title>Example Feed</title> 
     <link href="http://example.org/"/>
     <updated>2005-08-28T18:30:02Z</updated>
     <author> 
        <name>John Doe</name>
     </author> 
     <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
     ...
     <entry>
        <title>False Alarm on the Atom-Powered Robots Thing</title>
        <link href="http://example.org/2003/12/13/atom-powered-robot-retraction.html"/>
        <link rel="edit" href="http://example.org/app/877"/>
        <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-498593458954</id>
        <updated>2003-12-14T07:59:34Z</updated>
        <summary>Ooops</summary>
        <content type="xhtml" xml:lang="en" 
            xml:base="http://example.org/">
           <div xmlns="http://www.w3.org/1999/xhtml">
              <p><i>What can I say, the Atom menace
                 never materialized.</i></p>
           </div>
        </content>   
     </entry>
     <entry>
        <title>Atom-Powered Robots Run Amok</title>
        <link href="http://example.org/2003/12/13/atom-powered-robots-run-amok.html"/>
        <link rel="edit" href="http://example.org/app/876"/>
        <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
        <updated>2003-12-13T18:30:02Z</updated>
        <summary>Some text.</summary>
        <content type="xhtml" xml:lang="en" 
            xml:base="http://example.org/">
           <div xmlns="http://www.w3.org/1999/xhtml">
              <p><i>Film at eleven.</i></p>
           </div>
        </content>   
     </entry>
   </feed>

      

Section 11.3 Compound Entry

   An example of creating a new entry with an inline image. That is, the client
   has an image it must publish and an entry that includes an HTML 
   'img' element that uses that image. In this scenario we consider
   a client that has URIs of two Collection Resources. The first collection
   handles only 'text', 'html' and 'xhtml' entries. The URI of the first collection
   is: 

          http://example.net/blog/edit/

   and it has a Collection representation of:

   <?xml version="1.0" encoding="utf-8"?>
   <collection xmlns="http://purl.org/atom/app/">
      <member-type>entry</member-type>
      <search-template>http://example.net/blog/edit/{index}</search-template>
      <search-template>http://example.net/blog/edit/{daterange}</search-template>
   </collection>
   
   The second collection is a Generic Collection and is has
   a URI:

         http://example.net/binary/edit

   and has a Collection representation of:

   <?xml version="1.0" encoding="utf-8"?>
   <collection xmlns="http://purl.org/atom/app/">
      <member-type>generic</member-type>
      <search-template>http://example.net/binary/edit/{index}</search-template>
      <search-template>http://example.net/binary/edit/{daterange}</search-template>
   </collection>
   
  First the client uploads the image by POSTing to the 
  URI of the Generic Collection.

   POST /binary/edit/ HTTP/1.1
   Host: example.net
   User-Agent: Thingio/1.0
   Content-Type: image/png
   Content-Length: nnnn
   Title: A picture of the beach

   ...binary data...

   Which returns a 201 on success

   HTTP/1.1 201 Created
   Date: Fri, 25 Mar 2005 17:17:11 GMT
   Content-Length: 0
   Location: http://example.net/binary/edit/b/129.png


   Now the last step for the client is to POST the Atom Entry that 
   refers to the newly created image resource to the first
   Collection Resource. Note that the client takes the URI
   http://example.net/binary/readonly/129.png and uses it in
   the 'img' element in the Entry:

   POST  /blog/edit/ HTTP/1.1
   Host: example.net
   User-Agent: Thingio/1.0
   Accept: application/atom+xml
   Content-Type: application/atom+xml
   Content-Length: nnnn

   <?xml version="1.0" encoding="utf-8"?>
   <entry xmlns="http://www.w3.org/2005/Atom">
     <title>What I did on my summer vacation</title>
     <updated>2005-09-02T10:30:00Z</updated>
     <summary>Beach!</summary>
     <content type="xhtml" xml:lang="en" 
         xml:base="http://example.org/">
        <div xmlns="http://www.w3.org/1999/xhtml">
           <p>We went to the beach for summer vacation.
              Here is a picture of the waves rolling in:
              <img 
                   src="http://example.net/binary/readonly/129.png" 
                   alt="A picture of the beach."
              />
           </p>
        </div>
     </content>   
   </entry>

Section 9 becomes Section 12 and so on.

Section 11 IANA Considerations becomes Section 14 IANA Considerations. Also remove the registration of the application/atomserv+xml media-type.

Impacts

Notes

The cardnality of member-type should be 1 or more as opposed to 0 or more.

See also PaceProtocolResponseFormat


CategoryProposals