Copyright © 2002 W3C® (MIT, INRIA, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.
Annotea is a system for creating and publishing shareable annotations of Web documents. Built on HTTP, RDF, and XML, Annotea provides an interoperable protocol suitable for implementation within Web browsers to permit users to attach data to Web pages such that other users may, at their choice, see the attached data when they later browse the same pages. The Annotea protocol works without modifying the original document; that is, there is no requirement that the user have write access to the Web page being annotated. The Annotea protocol is suitable both for annotation data that is expected to be primarily for human viewing as well as annotation data that is expected to be consumed by other application programs, such as automatic classification tools, search engines, and workflow applications.
This section describes the status of this document at the time of its publication. This is a draft document and may be updated, replaced, or obsoleted by other documents at any time. The latest status of this document series is maintained at the W3C.
This document is a public DRAFT for discussion. It documents work that is part of the W3C Semantic Web Advanced Development project. This document is made available by W3C for discussion only. Publication of this document by W3C does not imply endorsement by W3C, including the Team and Membership.
The aim of this DRAFT document is to describe the general Annotea protocol as the authors currently see it. Separate documents will describe specific server and client implementations.
Our future plans include a revision of the protocol to add some extra information (attributions) about the origin of the data. The goal is to have better means to deal with metadata that is added to already existing annotations by other users and to be able separate that information when doing annotation or reply updates or deletes. This work is just beginning although the authors have done some experiments with their server implementation.
We expect to have more discussions in the www-annotation@w3.org mailing list about attributions and other protocol issues that may arise. Comments on this document may be sent to that mailing list, and are archived in a public archive.
This document describes a protocol for manipulating sharable annotations of Web documents. The protocol specifies how data is to be exchanged between a conforming client - an application that produces and consumes annotation data - and a service - an application that stores the data and supports query capabilities to return some or all of the stored data.
While clients are generally expected to present annotations visually in a graphical user interface, the Annotea protocol does not require nor does it assume that the data is generated or consumed by a visual tool. The Annotea protocol is equally suitable for use by applications to exchange data for non-visual uses by 'attaching' it to Web pages where no write access to the Web page is required.
An annotation service is an instance of an HTTP server that responds to the Annotea protocol at a specific URI. A single HTTP server might support multiple annotation services at the same host address; each such annotation service would have its own URI with the same 'host' portion. A site administrator may provide multiple annotation services on a single host as a convenience for simple clustering of annotations; e.g. multiple separate work groups, or for access control purposes, or for any other installation-dependent reason.
An Annotea capable client, such as Amaya, interacts with one or more annotation services using a set of protocols that are built on top of the HTTP protocol as described by this document.
Annotea currently specifies three kinds of protocols:
In addition to defining the above protocols, Appendix A describes a generalized RDF query language called Algae that is used to implement the queries described in Section 4.
Notation:
The examples in this document attempt to use the following Web addresses consistently to denote instances of the following classes of server or service:
http://annotea.example.org
http://annotea.example.org/Annotation
Annotation
script. The specific name of this script, and
thus the choice of the annotation service URI is chosen by the Web site
administrator.http://serv1.example.com/
http://serv2.example.com/
We distinguish the following types of client-server interactions supporting annotations and replies to annotations:
Annotea uses a standard HTTP POST message to publish a new annotation to the annotation service and HTTP GET messages to fetch any annotations and return the result to the client. HTTP POST provides the necessary interface for the server to construct a URI for the new annotation and return that URI to the client. With a URI for a previously created annotation, the client can (with the proper permissions) use HTTP PUT to modify the annotation and HTTP DELETE to delete an annotation. HTTP GET is used for querying an annotation service.
When a client creates a new annotation it posts RDF statements in an XML body that describe the new annotation resource to a selected annotation service. The client constructs an HTTP POST message containing the annotation as an anonymous RDF resource. The annotation service is responsible for allocating a URI for the annotation. The URI allocation mechanism is implementation dependent and not defined by this document.
The RDF/XML statements in the POST message define some information about the annotation; for example, a name for the user who created the annotation and the date on which it was created. The body of an annotation is a separate resource (Web document) that contains the material that the user wishes to convey through the annotation; that is, in a typical application the body would hold the text that a user entered to be the "content" of the annotation. The POST message must either refer to the URI of the body of the annotation (Section 2.1.1) or include the body in the message itself (Section 2.1.2). For both cases, the server sends back similar reply messages.
In the Annotea protocol, the body of the annotation can be a URI to an already existing document. As the body exists independently of the annotation, we refer to it as an external body. This section specifies the case in which an annotation is created using a known document as the annotation body.
In Figure 2.1 we show a request to the annotation service
whose Web address is http://annotea.example.org/Annotation
to
create a simple annotation that annotates the Web page
http://serv1.example.com/some/page.html
while using an existing
Web document http://serv2.example.com/mycomment.html
as the body
of the annotation. The creator of this annotation is identified as "Ralph
Swick". Note that the body of the annotation could be stored anywhere,
including serv1.example.com
or on the annotation server itself.
Figure 2.1 shows only a minimal set of HTTP headers.
POST /Annotation HTTP/1.1
Host: annotea.example.org
Content-Type: application/xml
Content-Length: 786
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/">
<r:Description>
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation"/>
<r:type r:resource="http://www.w3.org/2000/10/annotationType#Comment"/>
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<a:context>
http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])
</a:context>
<d:title>Annotation of Sample Page</d:title>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body r:resource="http://serv2.example.com/mycomment.html"/>
</r:Description>
</r:RDF>
The client must include an RDF type
property specifying
http://www.w3.org/2000/10/annotation-ns#Annotation
as (one of)
the annotation types and must include an
http://www.w3.org/2000/10/annotation-ns#annotates
property
identifying the Web document to which the annotation refers. The queries
specified in Section 2.2 rely on these two properties being present.
If the POST was not successful, the server should return a failure using any of the HTTP error statuses, such as those found in the 4xx family. If the POST was successful, the server responds with the status 201 Created.
If the POST was successful, the server creates a new annotation
and assigns it a URI. The server must then reply with a set of RDF statements
about the new annotation, giving the URI of the annotation that was posted
(see the Location: header and r:about
), and including the URI of
the document that was annotated (see a:annotates
) and the URI of
the annotation body (see a:body
). The reason for recalling the
URI of the body is that by doing so the server can share the same reply
regardless of which POST protocol was used.
Figure 2.2 shows a sample reply to the POST request sent in
Figure 2.1. The HTTP Location header and the RDF about
attribute
must match. The server may include in the reply other RDF statements in
addition to annotates
and body
. Clients may ignore
any of the RDF statements in the server reply that they do not need.
Note: the authors solicit feedback on whether any
implementations depend on having either the annotates
or
body
properties included in this reply.
HTTP/1.1 201 Created
Location: http://annotea.example.org/Annotation/3ACF6D754
Content-Type: application/xml
Content-Length: 432
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/">
<r:Description r:about="http://annotea.example.org/Annotation/3ACF6D754">
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<a:body r:resource="http://serv2.example.com/mycomment.html"/>
</r:Description>
</r:RDF>
This protocol places no restrictions on the specific URI that the server may choose for the annotation; the server is free to assign any URI that it wishes, though in general the URI should be on the same host as the annotation service. There also need not be any textual similarity between the URIs for annotations and the name of the annotation service itself.
An Annotea server is only required to support UTF-8 encoding. Clients are responsible for making conversions between other encodings before sending requests to the server.
In the case of a annotation with a new body, the client's POST message must include both the annotation metadata and the body of the annotation. The Annotea protocol is designed to permit the body to be a full XML document. The body is specified in the message as an anonymous resource. The server must allocate new URIs for both the annotation and for the body.
The Annotea protocol permits a new annotation body to have its own content type, just as an external body would have. Thus allows a client to use XML facilities such as XHTML, MATHML, and SVG in the body. At the same time, it was a design goal to minimize the number of server round-trips required to create an annotation. Therefore, Annotea specifies an RDF mechanism to publish a complete annotation in a single HTTP transaction and include the body as an separately identifiable XML document. From an architectural point of view, this mechanism to embed two XML documents in a single HTTP message is similar to the W3C XML fragment interchange work. Annotea pre-dates the XML fragment interchange working drafts. The authors have not decided whether to move to using that mechanism.
This Annotea protocol specifies a simple packaging protocol
that permits a client to specify embedded HTTP message bodies. To do this,
Annotea declares an RDF namespace for describing certain HTTP headers
(http://www.w3.org/1999/xx/http#
) and then a client specifies
those HTTP headers as normal RDF properties.
In Figure 2.3 we show a request to the annotation service
whose Web address is http://annotea.example.org/Annotation
to
create an annotation on the page
http://serv1.example.com/some/page.html
. The creator of this
annotation is also "Ralph Swick". The body of this annotation contains "This
is an important concept; see other page". The annotation
metadata specifies an annotation body (a:body
) using RDF
properties for the HTTP headers (h:ContentType
,
h:ContentLength
) and for the actual XHTML to be presented with
the annotation (h:Body
).
POST /Annotation HTTP/1.1
Host: annotea.example.org
Content-Type: application/xml
Content-Length: 1258
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/"
xmlns:h="http://www.w3.org/1999/xx/http#">
<r:Description>
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation"/>
<r:type r:resource="http://www.w3.org/2000/10/annotationType#Comment"/>
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<a:context>
http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])
</a:context>
<d:title>Annotation of Sample Page</d:title>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body>
<r:Description>
<h:ContentType>text/html</h:ContentType>
<h:ContentLength>289</h:ContentLength>
<h:Body r:parseType="Literal">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ralph's Annotation</title>
</head>
<body>
<p>This is an <em>important</em> concept; see
<a href="http://serv1.example.com/other/page.html">other page</a>.</p>
</body>
</html>
</h:Body>
</r:Description>
</a:body>
</r:Description>
</r:RDF>
The client must include an RDF type
property specifying
http://www.w3.org/2000/10/annotation-ns#Annotation
as (one of)
the annotation types and must include an
http://www.w3.org/2000/10/annotation-ns#annotates
property
identifying the Web document to which the annotation refers. The queries
specified in Section 2.2 rely on these two properties being present.
If the POST was not successful, the server should return a failure using any of the HTTP error status codes, such as those found in the 4xx family. If the POST was successful, the server responds with the status 201 Created.
If the POST was successful, the server creates a new
annotation, assigns it a URI, creates a separate body resource, and assigns
the body resource a URI. The server must reply with a set of RDF/XML
statements about the new annotation, giving the URI of the annotation (see
the Location HTTP header and r:about
), and including the URI of
the document that was annotated (see a:annotates
) and the URI of
the newly created body in an a:body
property as shown in Figure
2.4. The Location header and the RDF about
attribute describing
the new annotation must match. The server may return other implementation
dependent RDF statements as well, that a client may choose to ignore. Both
the annotation and the body URIs can be browsed as any other Web address
(i.e. with HTTP GET).
Note: the authors solicit feedback on whether any
implementations depend on having the annotates
property included
in this reply.
HTTP/1.1 201 Created
Location: http://annotea.example.org/Annotation/3ACF6D756
Content-Type: application/xml
Content-Length: 445
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/">
<r:Description r:about="http://annotea.example.org/Annotation/3ACF6D756">
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<a:body r:resource="http://annotea.example.org/Annotation/body/3ACF6D756"/>
</r:Description>
</r:RDF>
This protocol places no restrictions on the specific URIs that the server may choose for the annotation and for the body; the server is free to assign any URIs that it wishes, although in general the URIs should be on the same host as the annotation service. There need not be any textual similarity between the URIs for annotations and the URIs for their associated bodies, nor between the URIs for annotations and the name of the annotation service itself.
With this ad hoc packaging Annotea defines a POST method that explicitly creates two resources with a single message. This packaging protocol has the additional advantage that it makes POST of multiple resources an atomic operation; there is no time window in which another client might modify the annotation body after the annotation properties have been stored but before the body is stored.
A client queries an annotation service for the URIs of annotations it may hold by using the HTTP GET method. A service may support various kinds of queries, for example, to retrieve only the annotations made by a given user at a given time period.
This version of the Annotea protocol specification does not
include a full query language for annotations. Rather, since clients will
most commonly wish to query for annotations that have an
annotates
property naming a specific page that the user may
currently be viewing, the protocol specifices a particular URL query
parameter for passing the URI of the designated page to the server. This
provides a simple implementation for annotation clients and servers without
requiring the implementation of a custom query language. Appendix A describes
the Algae custom query language that the authors are currently experimenting
in the W3C sample annotation server.
Figure 2.5 shows the request that a client would issue if the user was
viewing the page http://serv1.example.com/some/page.html
and the
client wished to know what annotations of that page might be available at a
specific annotation service.
GET /Annotation?w3c_annotates=http://serv1.example.com/some/page.html HTTP/1.1
Host: annotea.example.org
Accept: application/xml
Figure 2.5 illustrates a sample annotation server query. As
with the POST requests shows above, the specific choice of URI; i.e
"/Annotation
" in this example, identifies a script on the server
that will handle the query. The name of this script and thus the full
annotation service URI is selected by the Web site implementor. The query
parameter w3c_annotates
must be used as shown; that is, the
script must recognize this specific parameter. The w3c_annotates
parameter may be best thought of as an abbreviation for the longer property
name http://www.w3.org/2000/10/annotation-ns#annotates
; that is,
this GET is a short-hand for a query that says "return the names of resources
that are the subjects of RDF statements in which the predicate is
http://www.w3.org/2000/10/annotation-ns#annotates and the object is
http://serv1.example.com/some/page.html".
The server responds to this GET request by returning RDF/XML
describing all the properties of each annotation that has an
annotates
relationship to the given URI. These properties
include the URI of the body resource. Figure 2.6 illustrates a typical
response; in this case there is only one annotation for the specified page. A
client should expect the query response to include the properties that are
described in the Annotea
RDF schemas. Depending on the implementation, the server may return other
RDF properties that are associated with the annotation. A client may choose
to ignore any properties it wishes.
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: 860
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/">
<r:Description r:about="http://annotea.example.org/Annotation/3ACF6D756">
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation"/>
<r:type r:resource="http://www.w3.org/2000/10/annotationType#Comment"/>
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<d:title>Annotation of Sample Page</d:title>
<a:context>
http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])
</a:context>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body r:resource="http://annotea.example.org/Annotation/body/3ACF6D754"/>
</r:Description>
</r:RDF>
As shown in Section 2.2, each annotation and the body of the annotation are associated with a distinct URI. Both the annotation and the body can be downloaded by browsing their respective URIs using the GET method. Figure 2.7 shows the request to retrieve the annotation that was created in Figure 2.3.
When downloading an annotation, the server should return all the properties associated with the annotation. These properties should include the ones that were in the original POST, and should also include other properties that may have been added by the server or by other users.
GET /Annotation/3ACF6D756 HTTP/1.1
Host: annotea.example.org
Accept: application/xml
For downloading the body that was created in Figure 2.3,
we just follow the URI that was given as the value of the a:body
property. This is illustrated in Figure 2.8.
GET /Annotation/body/3ACF6D756 HTTP/1.1
Host: annotea.example.org
Accept: application/xml
An existing annotation can be updated by using the PUT method and by specifying the URI of the annotation the client wishes to update.
Note: The use of HTTP PUT to modify annotations is the intended protocol as designed. For historical reasons, the W3C public Annotea service also implements a modification using POST. See Appendix B.
In this version of the Annotea protocol, clients MUST include in the PUT all the properties that they want the server to remember, whether they have changed or not. This includes the body contents if the body was stored in the annotation server. The service may choose to discard some of the properties that are sent by the client; for example, if the service intends to override those property values with other values determined by the service.
Note: In the future, the authors intend to develop a more flexible update protocol that permits updating a subset of the annotation properties without requiring clients to PUT every property and to permit clients to update some properties without re-publishing the annotation body.
Figure 2.9 illustrates a sample annotation update message
for the annotation whose URI is
http://annotea.example.org/Annotations/3ACF6D754.
The PUT
specifies the URI of the annotation that must be updated. This URI should
already exist in the annotation server. The body of this HTTP request is
similar to the one sent when first publishing the annotation (see Figure
2.3).
PUT /Annotations/3ACF6D754 HTTP/1.1
Host: annotea.example.org
Content-Type: application/xml
Content-Length: 1316
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/"
xmlns:h="http://www.w3.org/1999/xx/http#">
<r:Description r:about="http://annotea.example.org/Annotation/3ACF6D754">
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation"/>
<r:type r:resource="http://www.w3.org/2000/10/annotationType#Example"/>
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<d:title>Annotation of Sample Page</d:title>
<a:context>http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])</a:context>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T13:14Z</d:date>
<a:body>
<r:Description>
<h:ContentType>text/html</h:ContentType>
<h:ContentLength>250</h:ContentLength>
<h:Body r:parseType="Literal">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ralph's Annotation</title>
</head>
<body>
<p>This is an <em>important</em> concept; see
<a href="http://serv1.example.com/other/page.html">other page</a>.
</p>
</body>
</html>
</h:Body>
</r:Description>
</a:body>
</r:Description>
</r:RDF>
If the PUT is successful, the server should respond with status 200 OK. The server may respond with other HTTP status codes as appropriate for other circumstances.
The server responds to a PUT request by returning RDF/XML that recalls the URIs of the annotation and its body (see Figure 2.10). A client should expect to receive back the properties that are described in the Annotea RDF schemas. Depending on the implementation, the server may return other RDF properties that are associated with the annotation. A client may choose to ignore those extra properties.
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: 860
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/">
<r:Description r:about="http://annotea.example.org/Annotation/3ACF6D754">
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation"/>
<r:type r:resource="http://www.w3.org/2000/10/annotationType#Comment"/>
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<d:title>Annotation of Sample Page</d:title>
<a:context>
http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])
</a:context>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body r:resource="http://annotea.example.org/Annotation/body/3ACF6D754"/>
</r:Description>
</r:RDF>
An annotation is deleted using the DELETE method, specifying the URI of the annotation the client wishes to remove. All properties created with the original POST or updated with PUT messages are deleted so the server needs to maintain an association between these statements. For example, to delete the annotation created in the message illustrated in Figure 2.1 above, a client uses the message shown in Figure 2.11. If the body content was included in the POST as in Figure 2.3 the server should also delete the body resource.
If the DELETE is successful, the server should respond with status 200 OK. The server may respond with other HTTP status codes as appropriate in other circumstances.
DELETE /Annotation/3ACF6D754 HTTP/1.1
Host: annotea.example.org
HTTP/1.1 200 OK
Annotations are commonly thought of as comments that people can make about a Web document. To facilitate discussion about Web documents through the use of annotations, the Annotea protocol includes a separate class of resource called Reply. Replies are a mechanism that allows people to publish replies to annotations; for example, they allow someone to reply to a comment. Replies can also be made to other replies and thus promote threads of discussion. Moreover, as each reply is identified with a unique URI, the Annotea protocol also permits a client to annotate a reply.
Annotea does not define a dedicated RDF reply schema
independent of its annotation schema. A reply can be seen rather as a set of
RDF statements that include most of the Annotation RDF schema properties.
That is, an instance of a Reply will have most of the same properties that an
instance of an Annotation has. Two features distinguish a Reply from an
Annotation; the type
and the
http://www.w3.org/2000/10/annotation-ns#annotates
property.
Replies have RDF type http://www.w3.org/2001/03/thread#Reply
and
do not use the http://www.w3.org/2000/10/annotation-ns#annotates
property. They use instead two new properties defined in a Discussion Thread RDF
schema:
t:inReplyTo
whose value is the URI of the resource the
user is replying to (in this case, either an annotation or another
reply).t:root
whose value is the URI of the resource naming the
start of a discussion (in this case, the annotation that was first
replied to). This is used to identify a given discussion thread.Replies have the same four protocol operations that are defined for annotations:
When creating a new reply, a client posts RDF/XML statements that describe the new reply resource. The reply can be posted to the same server in which the thread root annotation is stored or to another server. All replies belonging to the same discussion thread MUST be stored in the same server; that is, a reply to a reply must be posted to the service that hosts the initial reply. This is to permit the annotation service to exercise full control over an entire thread; for example, to prohibit the deletion of a reply from the middle of a thread. Note that when a discussion thread is not stored in the same server as the annotation to which it is attached, there is no protection against making an orphan discussion thread; that is, the root annotation may be deleted, thus breaking the link from discussion thread to that annotation.
An instance of a reply is created using an HTTP POST message very similar to the messages described in Section 2.1. The RDF statements in the POST message identify the resource that is being replied-to, as well as the discussion thread to which the reply belongs. Other properties are identical to those discussed above for creating an annotation.
In Figure 3.1, we show the metadata that specifies a reply
to an annotation whose URI is
http://annotea.example.org/Annotation/3ACF6D754
. The creator of
this reply is identified as "Marja". This message includes the reply body.
The text of the reply body is "I agree with Ralph. What would be the next
step?".
POST /Annotation HTTP/1.1
Host: annotea.example.org
Content-Type: application/xml
Content-Length: 1254
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/"
xmlns:tr="http://www.w3.org/2001/03/thread#"
xmlns:h="http://www.w3.org/1999/xx/http#"
xmlns:rt:"http://www.w3.org/2001/12/replyType">
<r:Description>
<r:type r:resource="http://www.w3.org/2001/03/thread#Reply"/>
<r:type r:resource="http://www.w3.org/2001/12/replyType#Agree"/>
<tr:root r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<tr:inReplyTo r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<d:title>Annotation of Sample Page</d:title>
<d:creator>Marja</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body>
<r:Description>
<h:ContentType>text/html</h:ContentType>
<h:ContentLength>221</h:ContentLength>
<h:Body r:parseType="Literal">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Marja's Reply</title>
</head>
<body>
<p>I agree with Ralph. What would be the next step?</a>.</p>
</body>
</html>
</h:Body>
</r:Description>
</a:body>
</r:Description>
</r:RDF>
In this case, the new reply is the first one in the thread so the client
specifies the same value for the root
and inReplyTo
properties. A further reply to the reply created by this message would use
the same value for the root
property but would specify the URI
of the reply returned as shown in Figure 3.2 in its inReplyTo
property.
Like annotations, the annotation service creates a new Reply resource in response to the POST and returns its URI (Figure 3.2) with HTTP status code 201 Created. The server must reply with a set of RDF/XML statements about the newly created Reply resource, giving the URI of the Reply resource (see the Location HTTP header and r:about), and the URI of the newly created body in an a:body property as shown in Figure 2.4. The Location header and the RDF about attribute must match. The service may return other RDF statements.
HTTP/1.1 201 Created
Location: http://annotea.example.org/Annotation/2DCC6DF41
Content-Type: application/xml
Content-Length: 579
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/"
xmlns:tr="http://www.w3.org/2001/03/thread#">
<r:Description r:about="http://annotea.example.org/Annotation/2DCC6DF41">
<tr:root r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<tr:inReplyTo r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<a:body r:resource="http://annotea.example.org/Annotation/2DCC6DF41text"/>
</r:Description>
</r:RDF>
Note that as for annotations it is also possible to specify an
external body for a reply. The only change to the message shown in Figure 3.2
to specify an external reply body would be to use the URI of the external
body as the value of the a:body
property. The server response
will be the same except for this URI.
A client queries an annotation service for the URIs of
replies it may hold by using the HTTP GET method. Since clients will most
commonly wish to query for replies that have a root
property
naming a specific annotation that the user is viewing, a particular query
parameter is designated to pass the URI of that annotation, as shown in
Figure 3.3.
GET /Annotation?w3c_reply_tree=http://annotea.example.org/Annotation/3ACF6D754 HTTP/1.1
Host: annotea.example.org
Accept: application/xml
The query parameter w3c_reply_tree
may be best
thought of as an abbreviation for the longer property name
http://www.w3.org/2001/03/thread#root
; that is, this GET is a
short-hand for a query that says "return the names of resources that are the
subjects of RDF statements in which the predicate is
http://www.w3.org/2001/03/thread#root and the object is
http://annotea.example.org/Annotation/3ACF6D754".
The service responds to this GET request by returning a set
of statements expressed in RDF/XML describing each reply that has an
root
relationship to the specified root URI. Figure 3.4
illustrates a typical response; in this case there is only one reply for the
specified annotation.
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: 689
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/"
xmlns:tr="http://www.w3.org/2001/03/thread#">
<r:Description r:about="http://annotea.example.org/Annotation/2DCC6DF41">
<r:type r:resource="http://www.w3.org/2001/03/thread#Reply"/>
<r:type r:resource="http://www.w3.org/2001/03/thread#Agree"/>
<tr:root r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<tr:inReplyTo r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<d:title>Annotation of Sample Page</d:title>
<d:creator>Marja</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body r:resource="http://annotea.example.org/Annotation/2DCC6DF41text"/>
</r:Description>
</r:RDF>
The service must return all the properties for each Reply including the
type
, root
, and inReplyTo
properties
that facilitate a generation of a hierarchical thread view. The service may
return also additional RDF properties.
Both a reply and its body have distinct URIs. Each can be downloaded by using a GET method with the corresponding URI. Figure 3.5 shows how to download the reply created by the message of Figure 3.3 and Figure 3.6 shows how to download the body of the same reply.
GET /Annotation/2DCC6DF41 HTTP/1.1
Host: annotea.example.org
Accept: application/xml
If the request is successful, the server must reply with 200 OK and all the properties of the Reply it wishes the client to have in RDF/XML form. The server may reply with any of the HTTP status codes in other circumstances.
GET /Annotation/2DCC6DF41text HTTP/1.1
Host: annotea.example.org
Accept: application/xml
If the request is successful, the server must reply with 200 OK and the content of the Reply body. The server may reply with any of the HTTP status codes in other circumstances.
An existing reply is updated using the PUT method using the URI of the reply the client wishes to update.
Note: The use of HTTP PUT to modify replies is the intended protocol as designed. For historical reasons, the W3C public Annotea service also implements a modification using POST. See Appendix B.
In this version of the Annotea protocol, clients MUST include in the PUT all the properties that they want the server to remember, whether these properties have changed or not. This includes the body contents if the body was stored in the annotation server. The service may choose to discard some of the properties that are sent by a client; for example, if the service intends to override those property values with other values determined by the service. For example, to update the reply created in the message illustrated in Figure 3.1 above, a client can use the message in Figure 3.7.
PUT /Annotation/2DCC6DF41 HTTP/1.1
Host: annotea.example.org
Content-Type: application/xml
Content-Length: 864
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/"
xmlns:tr="http://www.w3.org/2001/03/thread#">
<r:Description r:about="http://annotea.example.org/Annotation/2DCC6DF41">
<r:type r:resource="http://www.w3.org/2001/03/thread#Reply"/>
<r:type r:resource="http://www.w3.org/2001/03/thread#Agree"/>
<tr:root r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<tr:inReplyTo r:resource="http://annotea.example.org/Annotation/3ACF6D754"/>
<d:title>Annotation of Sample Page</d:title>
<d:creator>Marja</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body r:resource="http://annotea.example.org/Annotation/2DCC6DF41text"/>
</r:Description>
</r:RDF>
A reply is deleted using the DELETE method, specifying the URI of the reply a client wishes to remove. All properties created with the original POST message or updated with PUT messages are deleted. For example, to delete the reply created in the message illustrated in Figure 3.1 above, a client uses the message in Figure 3.8.
DELETE /Annotation/2DCC6DF41 HTTP/1.1
Host: annotea.example.org
HTTP/1.1 200 OK
The server must respond with HTTP status code 200 OK if the delete was successful and may respond with any of the other HTTP status codes otherwise.
Deleting a reply in a middle of a discussion thread makes the rest of the thread orphaned. To prevent this, Annotea servers may define different policies for deleting and updating replies. For instance, it is possible to allow no deletions at all, allow just deletions of the replies when the reply is a leaf reply and does not have replies of its own, or define some other policies.
Note: The W3C public Annotea service does not allow deletions unless the reply is a leaf reply. If the reply is not a leaf reply, then successive replies on the thread must be deleted first.
In sections 2.2 and 3.2, we defined two URL query parameters for retrieving annotations and replies to annotations. If a client implements a user interface that presents all the annotations and replies in a hierarchical view, it might issue separate queries (GET requests) to the annotation service; one for retrieving the annotations and another to retrieve any threads rooted at each annotation.
When a client is viewing a specific annotation, however, it may prefer to issue a single query to the annotation service to return all the information about annotations and replies of that annotation.
If a client knows that it is making a query for statements
regarding an annotation, it may combine both query parameters in a single
request as shown in Figure 4.1. The query parameters that follow the
Annotation
fragment are indented below for better readability.
They should be concatenated on a single line when sending the request.:
GET /Annotation
?w3c_annotates=http://annotea.example.org/Annotation/3ACF6D754/2DCC6DF41
?w3c_reply_tree=http://annotea.example.org/Annotation/3ACF6D754/2DCC6DF41 HTTP/1.1
Host: annotea.example.org
Accept: application/xml
The result of the above request would be all the annotations and replies related to the given URI. As the above request could be misused (some clients may concatenate many queries in the same request), a server may refuse to honor the above request. An Annotea client must then make each request individually.
Development of Annotea and Algae is supported in part by funding from US Defense Advanced Research Projects Agency (DARPA) and Air Force Research Laboratory, Air Force Materiel Command, USAF, under agreement number F30602-00-2-0593, "Semantic Web Development" and also by Elisa Communications Oyj, Finland.
[Crawford90] J. Crawford. Access-Limited Logic: A Language for Knowledge Representation. UT Artificial Intelligence TR AI90-141, Department of Computer Sciences, University of Texas at Austin, Austin, Texas., Oct. 1990.
[Algae] http://www.w3.org/1999/02/26-modules/User/Algae-HOWTO.html
This is an informational appendix. Annotea clients and servers are not required to implement the Algae query language described here.
Algae is a query language that the authors have implemented in the W3C Annotea server. Algae provides general RDF queries to an annotation server in order to retrieve any set of RDF statements.
Users want to filter the annotations they see depending on what they are doing. For example, in order to unclutter a heavily annotated document, a user may want only to display annotations made by certain users, or attached to a part of the document, or that were modified in the past 24 hours, or that correspond to a combination of these filters. The filtering may be done locally by clients on the annotations that were already downloaded from the server or remotely, by means of the query string that will be sent to the service. Some of the service queries are going to happen frequently and clients can offer them through an easy graphical interface. Other more complicated queries can be offered through a generic "expert user" interface or to Semantic Web applications that want to utilize the annotation information as part of their operation.
The authors have adapted a form of query language syntax very
similar to the language used in Algernon [Crawford90] because it was
available from other prototyping work. This syntax uses triples in which
place-holder variables are denoted by names beginning with a questionmark,
such as ?annot
, a variable for an annotation URI. Contrary to
conventional RDF triple notations, the order of the items within Algae
triples is (predicate subject object). The triples, with their place-holder
variables, form a template (or pattern) that the Algae engine uses to locate
matching triples in its RDF data store. The template follows the 'ask'
instruction. The collect clause (:collect
) specifies the
properties that are desired in the output result of the query. For instance,
the query in Figure A.1 returns all the annotations attached to a document
http://serv1.example.com/some/page.html
with their annotation
URI (?annot
) and all the properties and values of that
annotation.
(namespace (rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#)
(a http://www.w3.org/2000/10/annotation-ns#)
(dc http://purl.org/dc/elements/1.1/)
ask
'((a::annotates ?annot http://serv1.example.com/some/page.html)
(?property ?annot ?value)
) :collect '(?annot ?property ?value))
It is also possible to explicitly enumerate each of the
properties that should be returned. The query in Figure A.2 returns all the
annotations attached to a certain document with their annotation URI
(?annot
), the context (?context
), the creator
(?creator
), the time created (?created
), the date
(?date
) and their annotation content URI (?body
).
The title is not returned here as it was not specified in this query. Note
that this query specifies that the triple pattern must include each of the
listed properties; if an annotation does not have a body
property then it will not be returned in this query result.
(namespace (rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#)
(a http://www.w3.org/2000/10/annotation-ns#)
(dc http://purl.org/dc/elements/1.1/)
ask
'((rdf::type ?annot a::Annotation)
(a::annotates ?annot http://serv1.example.com/some/page.html)
(a::context ?annot ?context)
(dc::creator ?annot ?creator)
(a::created ?annot ?created)
(dc::date ?annot ?date)
(a::body ?annot ?body)
) :collect '(?annot ?context ?creator ?created ?date ?body))
A typical answer to the query in Figure A.2 is shown in Figure A.3. It can consist of one or more annotation objects or return an empty result set indicating that no matching annotations were found. This RDF is processed by the browser and transferred to a format that is presented to the user.
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/">
<r:Description
r:about="http://annotea.example.org/CGI/annot?annotation=/2000/05/08-18:04:55">
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation" />
<a:annotates r:resource="http://serv1.example.com/some/page.html" />
<a:context>http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])</a:context>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body
r:resource="http://annotea.example.org/CGI/annot?body=/2000/05/08-18:04:55" />
</r:Description>
</r:RDF>
At the time of publication of this document, the authors' Amaya client can send the annotation server Algae queries by URL-encoded them, however it expects the query will be written in a manner such that the query result will contain all the information returned by the ?w3c_annotates response shown in Section 2.2. Figure A.4 illustrates a query that is equivalent to that shown in Figure A.1.
GET /Annotation?w3c_annotates=http://serv1.example.com/some/page.html
Host: annotea.example.org
Although the first published version of the Annotea protocol proposed the use of the HTTP PUT method for updating annotations, for some obscure reason that the authors have already forgotten (probably rushing to prepare a demo), we implemented this feature using an HTTP POST with a specialized query parameter.
This Appendix is not part of the Annotea protocols. As some clients and servers have implemented the messages described below, the authors are documenting it for the benefit of all. If other developers think it is interesting to support the update with POST, the authors will add it to the Annotea protocols. At the date of publication of this document, both Amaya (release 7.1) and the W3C Annotea server support this method. Amaya does not yet support an update with PUT, but the authors intend to make it do so and to stop using the update POST. The W3C Annotea server supports both POST and PUT updates.
As is the case for PUT, in the current version of the protocol, clients MUST include in the POST all the properties that they want the server to remember, whether those properties have changed or not. This includes the body as well if the body content was stored in the Annotea server. The server may choose to discard some of the properties that are sent back.
The authors acknowledge that requiring clients to update all the properties is not the best design. It should be seen just as an intermediary way of updating an annotation. A future version of the protocol should permit posting only the properties or a subset of the properties that have changed. It should also be possible to publish the annotation separately from the body.
Figure B.1 illustrates a sample annotation update message
for the annotation that was created in Figure 2.1. As with the PUT message
described above, the specific choice of URI; i.e. the Annotation
in this example, identifies a script on the server that will handle the
update. The annotation service URI used to POST an update is the same service
URI used to create new annotations and to query for existing annotations. The
query parameters that follow the Annotation
fragment are
indented below for better readability. They should be concatenated on a
single line when sending the request.
The query parameter replace_source
is used to
give the URI of the annotation that will be updated. The query parameter
rdftype
specifies the namespace for the RDF types of the
resource we're updating. In this case, it specifies the annotation
namespace.
The body of the request is similar to the one sent when first publishing the annotation. It should include all of the annotation metadata and the body that the client wants the server to store, whether or not that data has changed.
The server responds to this POST request by returning RDF/XML that repeats the URIs of the annotation and its body (see Figure B.2). A client should expect to receive back the properties that are described in the Annotea RDF schemas. Depending on the implementation, the server may return other RDF properties that are associated with the annotation. A client may chose to ignore those extra properties.
POST /Annotation
?replace_source=http://annotest.w3.org/Annotations/3ACF6D754
&rdftype=http://www.w3.org/2000/10/annotation-ns HTTP/1.1
Host: annotea.example.org
Content-Type: application/xml
Content-Length: 1316
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/"
xmlns:h="http://www.w3.org/1999/xx/http#">
<r:Description r:about="http://annotea.example.org/Annotation/3ACF6D754">
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation"/>
<r:type r:resource="http://www.w3.org/2000/10/annotationType#Example"/>
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<d:title>Annotation of Sample Page</d:title>
<a:context>http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])</a:context>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T13:14Z</d:date>
<a:body>
<r:Description>
<h:ContentType>text/html</h:ContentType>
<h:ContentLength>250</h:ContentLength>
<h:Body r:parseType="Literal">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ralph's Annotation</title>
</head>
<body>
<p>This is an <em>important</em> concept; see
<a href="http://serv1.example.com/other/page.html">other page</a>.
</p>
</body>
</html>
</h:Body>
</r:Description>
</a:body>
</r:Description>
</r:RDF>
HTTP/1.1 200 OK
Content-ype: application/xml
Content-Length: 860
<?xml version="1.0" ?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:a="http://www.w3.org/2000/10/annotation-ns#"
xmlns:d="http://purl.org/dc/elements/1.1/">
<r:Description r:about="http://annotea.example.org/Annotation/3ACF6D754">
<r:type r:resource="http://www.w3.org/2000/10/annotation-ns#Annotation"/>
<r:type r:resource="http://www.w3.org/2000/10/annotationType#Comment"/>
<a:annotates r:resource="http://serv1.example.com/some/page.html"/>
<d:title>Annotation of Sample Page</d:title>
<a:context>
http://serv1.example.com/some/page.html#xpointer(id("Main")/p[2])
</a:context>
<d:creator>Ralph Swick</d:creator>
<a:created>1999-10-14T12:10Z</a:created>
<d:date>1999-10-14T12:10Z</d:date>
<a:body r:resource="http://annotea.example.org/Annotation/body/3ACF6D754"/>
</r:Description>
</r:RDF>
$Revision: 1.314 $ of $Date: 2002/12/20 16:41:57 $ by $Author: swick $