Abstract
Unifies editing of entries, whether they are "plain Atom" or use a content from another media type (a.k.a. "media entries")
Status
Proposed (ThomasBroyer)
Keep in mind that english is not my native language, so wording can be tweaked a bit if it's too "tortured", at the discretion of the editors...
Rationale
Have an easy-to-explain, easy-to-implement way for uploading binaries and getting an address and a place to wrangle metadata.
The motivation for each constraint is explained. Constraints and uses that are copied from HTTP (for information) are explicitely marked as is, to avoid any ambiguity and eventually let HTTP evolve without having APP becoming out of sync and incompatible.
Most of the content of this Pace has already been exposed here http://www.imc.org/atom-protocol/mail-archive/msg05441.html
Proposal
In section 3 of draft-atom-protocol-09, replace definitions of Collection and Members as follows.
Collection - A resource that contains a set of Entries and has at least an Atom Feed Document representation. Entry - A resource that has at least an Atom Entry Document representation.
Then, everywhere in the document, replace Members with Entries.
Replace section 7.2.4 with the following:
7.2.4 The "app:accept" element
The app:collection element MAY contain one "app:accept" element. The
app:accept element value specifies a comma-separated list of media-
ranges [RFC2616] identifying the types of representations that can be
POSTed to the Collection's URI and will be treated as the content of the
Entry, or that can be POSTed to the Collection's URI as the inline content
of an Atom Entry Document. In particular, types of representations from
which the server will derive an Atom Entry Document representation
rather than use it as the content of the entry MUST NOT be listed here.
If the "application/atom+xml" is listed (or is matched by a listed media-
range), this means a client might send an Atom Entry Document whose
"atom:content" element contains an Atom Entry or Atom Feed Document.
Section 8.2 "Creating Entries" discusses these possible server behaviors.
Whitespace separating the media-range values is considered insignificant
and MUST be ignored.
The app:accept element is similar to the HTTP Accept request-header
[RFC2616] with the exception that app:accept has no notion of
preference. Accordingly, the value syntax of app:accept does not use
accept-params or "q" parameters as specified in [RFC2616], section
14.1. The order of media-ranges is not significant. The following
lists are all equivalent:
<app:accept>image/png, image/*</app:accept>
<app:accept>image/*, image/png</app:accept>
<app:accept>image/*</app:accept>
The special value "entry" indicates that Atom Entry Documents can be
posted to the Collection using an "atom:content" element with a type
value of "text", "html" or "xhtml". If the app:accept element is omitted,
or empty, the collection SHOULD be interpreted as if the "app:accept"
element were present with a value of "entry".
appAccept =
element app:accept {
appCommonAttributes,
( appTypeValue? )
}
appTypeValue = ( "entry" | media-type | entry-or-media-type )
media-type = xsd:string { pattern = "(.+/.+(;.+=(".+"|.+))*,?)*" }
entry-or-media-type = xsd:string { pattern = "entry,(.+/.+(;.+=(".+"|.+))*,?)*" }
Please note that the above patterns are not really accurate (I can provide exact ones if needed), but as the Relax NG schema is not normative, it shouldn't count in this Pace discussion.
Replace sections 8, 9 and 10 with sections 8 and 9 as follows:
8. Working with Collections Clients have two ways of interacting with Collections: they can list Collections' membership and the can create new Entries inside Collections.
Insert here section 9. "Listing Collections", renumbered as section 8.1, then follow on with:
8.2 Creating Entries
To add entries to a collection, clients send POST requests to the
collection's URI. The server then creates a resource with at least an
Atom Entry Document representation.
If the body of the request is an Atom Entry Document, then the Atom
Entry Document representation of the created resource MUST be derived
from it. For example, servers might mint a new "atom:id" value, fix spelling
errors in textual content, add or remove categories, make an inline content
out-of-line (if possible), etc.
If the body of the request is not an Atom Entry Document, then the Atom
Entry Document representation of the created resource MAY use the
body of the request (or a derived form) as the content of the entry, either
inlined in the atom:content element or referenced using a "src" attribute.
[@NOTE@: note that this leaves place for implementing 2WayRSS,
Annotea, HTML-form (multipart/x-form-data) processing or other protocols
at the same URI]
This specification does not define what's the result of POSTing an Atom
Feed Document and servers MAY reject such entities using 422
(Unprocessable Entity) or 400 (Bad Request) status codes.
If an entry was created in the collection which received the POST, its URI
(the URI of the Atom Entry Document) MUST be returned in a Location
header in the 201 ("Created") response. If the entry has been accepted but
not yet created, the URI where it will be available (if it ever is) MUST be
returned in a Location header in the 202 ("Accepted") response.
Clients MUST NOT assume that the URI provided by the Location header can
be used to edit the created entry: the created entry MAY NOT be editable,
or the URI used to edit it MAY be a different one. Section 9.1.1 discusses how
servers indicate the URI to be used to edit an entry.
As clients are likely to issue a GET to the URI given in the Location header
of 201 ("Created") responses, to retrieve at least some basic information
such the entry's atom:id, a server might want to return the entry in the
body of the response. Per [HTTP/1.1], to unambiguously tell the client that
the response body is a representation of the resource identified by the
URI in the Location header, the server has to include a Content-Location
header with the same value. To remove any ambiguity with respect to URI
normalization and comparison, this specification allows clients to
OPTIONALLY compare Location and Content-Location values character by
character. Even in the presence of such a Content-Location header (with the
same value as the Location response header), clients MUST NOT assume that
the response body is an Atom Entry Document, as content negotiation might
have been used. If the response body is an Atom Entry Document, clients
MUST NOT assume that it is a full representation of the member resource or
the exact same representation that could be retrieved at the URI given in
the Location header.
Collections MAY impose constraints on the media-types of request entities
POSTed to the collection and MAY generate a response with a status code
of 415 ("Unsupported Media Type"). [@TBD@: not sure this is the place to
talk about it, maybe near app:accept would be a better place]
8.3 Examples of Entry Creation
This section contains examples of sending an Atom Entry and a JPEG image
to a collection.
8.3.1 Sending an Atom Entry to a Collection
Below, the client sends a POST request containing an Atom Entry to the URI
of the Collection:
POST /edit/myblog/entries HTTP/1.1
Host: example.org
User- Agent: Thingio/1.0
Content- Type: application/atom+xml
Content- Length: nnn
<?xml version="1.0" ?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>Atom-Powered Robots Run Amok</title>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<author><name>John Doe</name></author>
<content>Some text.</content>
</entry>
The server signals a successful creation with a status code of 201. The
response includes a "Location" header indicating the URI of the Atom
Entry and a representation of that entry in the body of the response
(the server indicates that the entry is a representation of the created
resource with the "Content-Location header", having the same value as
the "Location" header).
HTTP/1.1 201 Created
Date: Fri, 7 Oct 2005 17:17:11 GMT
Content- Length: nnn
Content- Type: application/atom+xml; charset="utf-8"
Content- Location: http://example.org/edit/myblog/entries/first
Location: http://example.org/edit/myblog/entries/first
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>Atom-Powered Robots Run Amok</title>
<id>tag:example.org,2005-10-07:myblog:entries:first</id>
<updated>2005-10-07T17:17:11Z</updated>
<author><name>John Doe</name></author>
<content>Some text.</content>
<link rel="alternate" type="text/html"
href="http://example.org/myblog/entries/first" />
<link rel="edit" type="application/atom+xml"
href="http://example.org/edit/myblog/entries/first" />
</entry>
Note that the entry created by the server does not exactly match the
entry POSTed by the client. In particular, the server has changed the values
of various elements in the entry such as the atom:id and atom:updated, and
has added an atom:link with a rel value of "alternate" to communicate the
URI of an alternate representation (here, in HTML) of the entry, and an
atom:link with a rel value of "edit" (this is discussed in Section 9.1.1).
8.3.2 Sending a JPEG image to a collection
Below, the client sends a POST request containing a JPEG image to the URI
of the Collection, along with a Title header and authorization credentials:
POST /edit/myblog/photos HTTP/1.1
Host: example.org
User- Agent: Thingio/1.0
Content- Type: image/jpeg
Content- Length: nnn
Title: Sunrise on Miami Beach
Authorization: Basic ZG9lOmpvaG4=
...binary data...
The server signals a successful creation of the resource and its Atom
Entry Document representation with a status code of 201. The
response includes a "Location" header indicating the URI of the Atom
Entry and a representation of that entry in the body of the response
(the server indicates that the entry is a representation of the created
resource with the "Content-Location" header, having the same value as
the "Location" header).
HTTP/1.1 201 Created
Date: Fri, 7 Oct 2005 17:17:11 GMT
Content- Length: nnn
Content- Type: application/atom+xml; charset="utf-8"
Content- Location: http://example.org/myblog/photos/SunriseOnMiamiBeach.atom
Location: http://example.org/myblog/photos/SunriseOnMiamiBeach.atom
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>Sunrise on Miami Beach</title>
<id>tag:example.org,2005-10-07:myblog:photos:SunriseOnMiamiBeach</id>
<updated>2005-10-07T17:17:11Z</updated>
<author><name>John Doe</name></author>
<summary>Sunrise on Miami Beach</summary>
<content type="image/jpeg" src="SunriseOnMiamiBeach.jpg" />
<link rel="edit" type="application/atom+xml"
href="http://example.org/edit/myblog/photos/SunriseOnMiamiBeach.atom" />
<link rel="edit" type="image/jpeg"
href="http://example.org/edit/myblog/photos/SunriseOnMiamiBeach.jpg" />
</entry>
Note that the server here has used the provided title to mint the URI
of the created resource along with its "atom:id". It has also used it as
the entry summary, which is mandatory for the entry to be a valid Atom
Entry Document. Here, the author of the entry might have been derived
from the authenticated user, or it might have been defined by a server
configuration.
9. Working with Entries
There are two ways of interacting with Entries: editing them to update their content and deleting them.
9.1 Editing Entries
Editing an Entry consists in sending an updated representation of the
Entry to the server using a PUT request. The IRI to which to send the
updated representation is called the representation's Edit IRI and each
representation might have its own Edit IRI.
As every Entry has a mandatory Atom Entry Document representation,
this representation's Edit IRI is also called the Entry's Edit IRI.
9.1.1 Retrieving the representation's Edit IRI
Servers expose every editable representation of an Entry by including
links with a rel value of "edit" in its Atom Entry representation. Each one
of these links identifies an editable representation and gives its Edit IRI
as the value of the "href" attribute.
Clients selects the appropriate representation's Edit IRI depending on
the media type and language of the updated representations it wants
to send to the server.
In Atom Feed representations of Collections, servers MAY expose only
a single link with a rel value of "edit", whose href value identifies the
Atom Entry Document representation of the Entry, where every other
editable representation will be exposed. Consequently, clients SHOULD
retrieve the Atom Entry Document representation of an Entry in order to
discover every one of its editable representations.
9.1.1.1 The "edit" Link Relation
An atom:entry element MUST NOT contain more than one link with a rel
value of "edit" that has the same combination of type and hreflang
attribute values. If the type attribute is not present, the link element MUST
be interpreted as if it were present with a value of "application/atom+xml".
If the hreflang attribute is not present, the element MUST be interpreted
as if it were present with a value equal to the in-scope "xml:lang" attribute
value, defaulting to the Content-Language HTTP header value if there is
no in-scope "xml:lang" attribute, and to an undefined language if there is
no Content-Language header either.
On a link with a rel value of "edit", a type value of "application/atom+xml"
always identifies an Atom Entry Document representation, never an
Atom Feed Document.
The meaning of a link with a rel value of "edit" at the feed level (i.e. as a
direct child of an atom:feed element) is not defined.
9.1.2 Updating an Entry
To update an Entry, clients send an updated representation in the body
of a PUT request to the appropriate representation's Edit IRI.
To avoid lost updates, clients SHOULD send precondition headers (e.g.
If-Not-Modified-Since or If-Match) in their PUT requests. This also means
servers SHOULD send accurate values in Last-Modified or ETag headers
and SHOULD honour precondition headers, responding with a 412
(Precondition Failed) status code when appropriate.
[@NOTE@: should we add an informative reference to
http://www.w3.org/1999/04/Editing/ @]
9.1.3. Editing Entries with Unrecognized Metadata
To avoid unintentional loss of data, Atom Protocol clients SHOULD preserve
all metadata, including HTTP entity-headers and unknown HTTP headers and
unknown foreign markup as defined in Section 6 of [RFC4287], which has
not been intentionally modified.
9.2 Deleting Entries
To delete an entry and remove it from collections, clients send a DELETE
request to the Entry's Edit IRI, i.e. the Edit IRI of the Atom Entry Document
representation of the Entry.
If an Entry can be deleted but its Atom Entry Document is not editable, a
server still has to expose a link with a rel value of "edit" and a type value
of "application/atom+xml" and it will respond to PUT requests with a 4xx
status code (for example, 405 Method Not Allowed, 403 Forbidden
or 401 Unauthorized).
Impacts
Actually makes things even better
