Web Structured, Schema’d & Searchable (Web3S)

Date: 5/3/2007 9:45:00 PM

 

© 2007 Microsoft Corporation.  This specification licensed under the Creative Commons Attribution 3.0 United States copyright license, available at: http://creativecommons.org/licenses/by/3.0/us/legalcode.  All other rights reserved.


PDF version of this specification

1        Summary

The purpose of this document is to define a protocol that is a good fit for Live Contacts. Live Contacts is the central data store in Windows Live for address book information. All Hotmail contacts, Messenger buddies and Spaces’ friends are recorded in Live Contacts. There are currently approximately 500,000,000 active address books in Live Contacts.

 

The key issues that Live Contacts faces in terms of designing a protocol to let third parties access it are:

 

Simplicity – The target audience for Web3S are web developers and their code runs in a dizzying array of operating systems, application execution environments, programming languages, tool kits, etc. Many of these environments are completely custom so we can’t just hand out sample code for all of them. This means that many people wanting to interact with us will have to build their own libraries to do so from scratch. As such it is critical that our protocol be as simple as possible. We have therefore chosen to take a straight forward HTTP approach where our resources are all URI addressable and use the standard RFC 2616 methods (DELETE/GET/PUT/POST). We have introduced, however, a new method – UPDATE. This method was introduced to deal with a specific issue that comes up with some of the more complex schemas. We have also defined a very simple data infoset that can be easily serialized into/out of XML and JSON. We feel that there are important communities that want to interact with us via both XML and JSON so we wanted a system simple enough to properly support both.

 

Cost of Read/Writes – Although Live Contacts presents a view of a single coherent data structure that contains all the information in a particular address book in reality the data is spread across numerous tables. Therefore when someone asks for an entire address book their request will kick off numerous read requests. Similarly when someone asks to update an entire contact or even an entire address book their update will cause numerous writes to many tables.

To address this problem every value in an address book is individually addressable with a URL using a path language (e.g. https://example.com/.../com.example.contacts/com.example.contact(123)/com.example.firstname). Therefore every single part of the address book is an addressable resource that can be interacted with using DELETE/GET/POST/PUT/UPDATE HTTP methods. This enables read and writes to occur at the level that makes most sense. It also has the happy side effect of enabling scenarios we never thought of by giving names to everything. Naming is power and in Web3S everything has a publicly addressable name.

In addition all writes are merge, not replacement based. In a replacement system if someone wanted to update a contact’s value they would have to upload the entire contact, even if they are just changing one value. This is prohibitively expensive for Live Contacts as it requires touching many tables without actually doing any useful work.  So instead we specify the use of merge semantics. Only explicitly named fields with no values will be changed, all other fields will be ignored. This enables write requests to only specify values that need to be changed.

 

Versioning – Live Contacts is constantly adding new fields to its address book schema. This creates a challenge because we cannot rely on clients being updated when new fields are added. So it’s critical that both older clients and newer clients can coexist with Live Contacts data without stepping on each other.

To address this issue in the case of querying content (e.g. GET) we require that all clients implement an ignore rule – that is, clients must ignore data they don’t recognize. This means that when new values are added older clients won’t ‘see’ them and thus not break.

In the case of writes (e.g. PUT/POST/UPDATE) we use merge semantics. This means that only fields that are explicitly specified by the client are changed, other fields are left alone. So if a V1 client updates a contact with V2 fields none of the V1 client’s update requests will affect the V2 fields since none of those fields will be mentioned in the V1 client’s request.

2        Table of Contents

Web Structured, Schema’d & Searchable (Web3S) 1

1       Summary. 1

2       Table of Contents. 2

3       Terminology. 4

4       An Introductory Example. 4

5       The Web3S Resource Infoset 8

6       Syntax for representing a Web3S Infoset Instance. 10

7       Addressing Web3S Information Items in HTTP. 11

8       Web3S Content Types. 12

8.1        Common Requirements for all MIME types. 12

8.1.1         Example. 13

8.2        Application/Web3S+xml Mime Type. 14

8.2.1         Example. 17

8.3        Application/Web3S+xml with Merge Semantics. 18

8.3.1         Example. 20

8.4        Application/Web3SDelta+xml Mime Type. 21

8.4.1         Example. 22

8.5        Application/Web3SDefPage+xml Mime Type. 22

8.5.1         Deferred Content 23

8.5.2         Paging. 24

8.5.3         Example. 25

9       Web3S Resources & HTTP Methods. 27

9.1        Common Requirements For All Web3S Methods. 27

9.1.1         Well Formed Request-URI Requirement 27

9.1.2         Optimistic Concurrency. 27

9.1.3         511 – Response Too Large. 29

9.2        GET. 30

9.3        OPTIONS. 30

9.4        PUT/POST/DELETE/UPDATE Common Requirements. 30

9.5        DELETE. 31

9.6        POST. 32

9.6.1         Example. 32

9.7        PUT/UPDATE Common Requirements. 33

9.8        PUT. 33

9.8.1         Example. 34

9.9        UPDATE. 36

9.9.1         Example. 36

10         Extended Options. 39

10.1      Location Information. 39

10.2      Web3S Location Information. 39

10.3      Sort Query Segment Extension. 39

10.3.1       Example. 40

10.4      XPATH Query Segment Extension. 41

10.5      SEARCH Method Support 41

10.6      Serializing the Web3S Infoset into/out of JSON.. 41

11         Appendix. 41

11.1      Normative References. 41

11.2      MUST Requirements. 41

11.3      SHOULD Requirements. 46

11.4      MAY Requirements. 46

11.5      Open Issues. 46

11.6      Last Used Requirement ID. 48

 

3        Terminology

Information Set (Infoset) – A model that represents the information Web3S can describe.

 

Schema – A theoretical entity that captures the syntax and semantics of a Web3S resource, the actual representation of the schema (if any) is not constrained by this spec. (Read: No, this has nothing to do with XML Schema.)

 

Single Valued – An element information item (EII) whose schema forbids it have any sibling EIIs with the same name.

 

Multi-valued – An EII whose schema explicitly allows or even requires that the EII have siblings with the same name.

 

Root EII – The EII that roots an instance of the Web3S Infoset.

 

Non-Web3S Prefix Path – The part of a HTTP URL path that points to a Web3S root EII. For example, if the root EII com.example.lists is addressable as http://example.com/web3sparser/joesstuff/com.example.lists and com.example.lists is a Web3S resource then web3sparser/joestuff is the non-Web3S prefix path.

 

Full Name – In the case of single valued EIIs this is the value of the name property of the EII. In the case of multi-valued EIIs this is the combination of the value of the name and ID properties.

 

Annotation Command – In the context of Application/Web3SDefPage+xml and Application/Web3SDelta+xml this is an XML element included in the XML serialization that is intended to be interpreted as a command to the parser of the message rather than a description of a member of the Web3S infoset.

4        An Introductory Example

A Web3S client wishes to get its first copy of a user’s address book. The address book is represented as an XML document. Each element in the address book is individually addressable via XPATH style syntax in the request URI. But to kick things off the client asks for the entire address book.

 

GET /someuser@example.com/LiveContacts/com.live.livecontacts.livecontacts HTTP/1.1

Host: cumulus.services.live.com

Accept: application/Web3S+xml

 

 

HTTP/1.1 200 OK

Content-Type: application/Web3S+xml

 

<LiveContacts xmlns=”Web3SBase:com.live.livecontacts”

              xmlns:Web3S = “Web3S:”>

   …

   <Contacts>

      <Contact>

         <Web3S:ID>123ABC</Web3S:ID>

         <Profiles>

            <Personal>

               <FirstName>Karina</FirstName>

               <MiddleName>Normann</MiddleName>

               <LastName>jacobsen</LastName>

            </Personal>

         </Profiles>

         <Phones>

            <Phone>

               <Web3S:ID>9993</Web3S:ID>

               <Number>+15555555555</Number>

            </Phone>

            <Phone>

               <Web3S:ID>123A</Web3S:ID>

               <Number>+15555551234</Number>

            </Phone>

         </Phones>

      </Contact>

   </Contacts>

</addressbook>

Example 1 - GET request/response for the contents of an address book

All elements in the Web3S infoset are named using reverse domain names. So the ‘proper’ name of the root element is com.live.livecontacts.addressbook. To make it easy to serialize into XML we split the name such that the last segment becomes the XML localname and the rest of the DNS name, prefixed with the protocol identifier Web3SBase becomes the namespace.

 

The Web3S infoset also recognizes the difference between single valued and multi-valued elements. A multi-valued element is one that can appear multiple times in the schema. In the GET both com.live.livecontacts.contact and com.live.livecontacts.phone are examples of multi-valued elements. Multi-valued elements always have an ID that enables multiple values of the elements to be distinguished from each other.

 

PUT /someuser@example.com/LiveContacts/com.live.livecontacts.livecontacts/com.live.livecontacts.contacts/com.live.livecontacts.contact(123ABC) HTTP/1.1

Host: cumulus.services.live.com

Content-Type: application/Web3S+xml

 

 

<Contact xmlns=”Web3SBase:com.live.livecontacts”

         xmlns:Web3S = “Web3S:”>

   <Profiles>

      <Personal>

         <lastname>Jakobsen</lastname>

      </Personal>

   </Profiles>

   <Phones>

      <Phone>

         <Web3S:ID>123A</Web3S:ID>

         <Number>+15555555678</Number>

      </Phone>

   </Phones>

</Contact>

 

 

HTTP/1.1 200 OK

Example 2 - A PUT request/response to update a last name and number in an address book

The PUT is addressed to the contact element with the ID 123ABC and yes, the ID element is intentionally omitted in the body of the request. The PUT instructs that com.live.livecontacts.lastname and com.live.livecontacts.number be changed. All other values are left unaltered as PUT with the application/Web3S+xml MIME type uses merge semantics.

 

POST /someuser@example.com/LiveContacts/com.live.livecontacts.livecontacts/com.live.livecontacts.contacts HTTP/1.1

Host: cumulus.services.live.com

Content-Type: application/Web3S+xml

 

<Contact xmlns=”Web3SBase:com.live.livecontacts”

         xmlns:Web3s = “Web3S:”>

   <Web3s:ID/>

   <Profiles>

      <Personal>

         <FirstName>Manish</FirstName>

      </Personal>

   </Profiles>

</Contact>

 

HTTP/1.1 201 Created

Location: http://cumulus.services.live.com/someuser@example.com/com.live.livecontacts.livecontacts/com.live.livecontacts.constacts/com.example.contact(43432)

Content-Type: application/Web3s+xml

 

<Contact xmlns=”Web3SBase:com.example”

         xmlns:Web3s = “Web3S:”>

   <Web3s:ID>43432</Web3s:ID>

   <Profiles>

      <Personal>

         <FirstName>Manish</FirstName>

      </Personal>

   </Profiles>

</Contact>

 

Example 3 - A POST request/response to add an entry to an address book

In this example the client appends a new contact using POST to the address book. The IDs are left empty because the server has to decide on their value.

 

DELETE /someuser@example.com/LiveContacts/com.example.addressbook/com.example.contact(123ABC)/com.example.phones/com.example.phone(9993) HTTP/1.1

Host: cumulus.services.live.com

 

HTTP/1.1 200 OK

Example 4 - DELETE request/response to remove a phone number from an address book

Using the same URI syntax it’s possible to delete at any level, in this case an individual number is deleted.

 

UPDATE /someuser@example.com/LiveContacts/com.live.livecontacts.livecontacts HTTP/1.1

Host: cumulus.services.live.com

Content-Type: application/Web3SDelta+xml

 

<LiveContacts xmlns=”Web3SBase:com.example”

              xmlns:Web3S = “Web3S:”>

   <Contacts>

      <Contact>

         <Web3S:ID>123ABC</Web3S:ID>

         <Profiles>

            <Personal>

               <LastName>Jakobsen</LastName>

            </Personal>

         </Profiles>

         <Phones>

            <Web3S:delete>

               <Phone>

                  <Web3S:ID>9993</Web3S:ID>

               </Phone>

            </Web3S:delete>

            <Phone>

               <Web3S:ID>123A</Web3S:ID>

               <Number>+15555555678</Number>

            </Phone>

         </Phones>

      </Contact>

      <Contact>

         <Web3S:ID/>

         <FirstName>Manish</FirstName>

      </Contact>

</LiveContacts>

 

HTTP/1.1 200 OK

Example 5 - Use UPDATE to perform the same actions as the previous three methods

UPDATE is used by Web3S to enable multiple simultaneous changes to a data structure. The method was necessitated by more complex schemas where fields had dependent values and therefore certain changes could only be made to the schema if all parts of the change were made at once. In the previous example the four changes made by the previous three methods (change the com.live.livecontacts.lastname and com.live.live.contacts.phone elements, delete a phone number and add a new contact) are all made in a single method request.

5        The Web3S Resource Infoset

The Web3S infoset consists of two information items, the element information item (EII) and the string information item (SII).

 

For modeling purposes each of the externally viewable representation of these information items is described by the properties specified below. The manifestation of the information items on the wire is determined by the serialization in use.

 

Element Information Item (EII) Properties

Property Name

Property Description

Name

A globally unique name consisting of a reverse DNS name (e.g. com.live.livecontacts.firstname).

 

Note however that RFC 3490 encoding is not necessary, unicode characters can be used directly at the infoset level. How this translates to serializations (from URLs to XML to JSON) depends on the serialization’s own character encoding rules.

Parent

If the EII is the root then this value is empty. Otherwise this value must point to a single EII that contains this EII.

 

EIIs must always form acyclic single rooted trees.

Children

This value can be:

·        empty,

·        point to a single string information item or

·        point to a collection of element information items.

ID

Used to disambiguate multiple sibling instances of EIIs that have the same name.

 

This value does not exist for single valued EIIs. This value is a string for multi-valued EIIs.

 

ID values are only guaranteed to be unique amongst sibling EIIs of the same name. Re-use of IDs (e.g. after an EII with a particular ID is deleted) is discouraged but is not prevented.

 

com.example.root

   com.example.child(12)

      com.example.grandchild(12)

      com.example.grandchild(abc)

      com.example.adoptedgrandchild(12)

   com.example.child(abc)

      com.example.grandchild(12)

      com.example.starchild

Example 6 - Demonstrating of Web3S ID rules

In the previous example the ID values 12 and abc get used over and over again. That is legal. The ID requirements only specify that EIIs with the same name that are siblings have to have different ID values.

 

com.example.child(12) and com.example.grandchild(12)  can both have the same ID because they are not siblings.

 

com.example.child(12) and com.example.child(abc) can both contain EIIs with the name com.example.grandchild(12) even though both EIIs have the same name, com.example.grandchild, because they do not share the same parent.

 

com.example.grandchild(12) and com.example.adoptedgrandchild(12) can both have the ID because even though both EIIs are siblings they do not have the same name.

 

Finally, com.example.adoptedgrandchild(12) and com.example.grandchild(12) have IDs while com.example.starchild doesn’t even though all of these elements appear only once under their respective parents. What a reader can immediately determine from the infoset example even though no schema has been provided is that com.example.adoptedgrandchild must have a schema that defines it as multi-valued and com.example.starchild must have a schema that defines it as single valued. Multi-valued EIIs must always have IDs, even if there is only a single instance of them in a particular Web3S infoset instance while single valued EIIs must never have IDs.

 

By default Web3S resources do not allow an ordering of the values in the children property. However when a Web3S message is in transit (e.g. being sent over the wire) the serialization can have an ordering and that ordering can be semantically meaningful. Put another way, children are unordered on disk but can optionally be ordered inside of a message on the wire.

 

String Information Item (SII) Properties

Property Name

Property Description

Value

This value must contain an ordered series of one or more unicode characters.

 

Note that there is no explicit ‘empty string’ value in the Web3S infoset.

Parent

This value points to a single EII that contains this SII.

 

When we refer to Unicode it is to the abstract Unicode character planes rather than to any specific encoding (e.g. utf-8, 16, 32, etc.)

6        Syntax for representing a Web3S Infoset Instance

The following provides a short hand notation for presenting an instance of a Web3S infoset. The short hand is only used for illustrative purposes and has no normative standing beyond its use for illustrations in this spec.

 

org.example.contacts

   org.example.contact(2344)

      org.example.contactType

         org.example.work

      org.example.firstname

         “Inbar”

      org.example.lastname

         “Gazit”

   org.example.contact(1)

      org.example.contactType

         org.example.home

      org.example.firstname

         “Marina”

      org.example.lastname

         “”

Example 7 - An instance of a Web3S Infoset

In this example the EII org.example.contacts contains two org.example.contact EIIs with the IDs 2344 and 1 respectively. In this example each of the contact EIIs contain the same three children, contactType, firstname and lastname. The children of firstname and lastname are strings. In the org.example.contacts/org.example.contact(1) example the lastname value is the empty string (e.g. the explicit value “”, this is distinct from having no children). The contactType EIIs contain a single EII who has no children.

 

As this short hand notation is only intended for illustrative purposes and is not intended as an actual serialization no formal definition is provided.

7        Addressing Web3S Information Items in HTTP

In order to enable maximum flexibility EIIs are directly exposed as HTTP resources. That is, each EII can be addressed as a HTTP resource and manipulated with the usual methods. To keep things simple we have chosen not to make SIIs URL addressable although that is functionality that could be added later.

 

3SAAB – The root EII of a Web3S resource MUST either be addressed at the root of the HTTP URL path (e.g. “/” + the full name of the root EII) or its parent in the path MUST NOT be a Web3S resource.

 

3SAAE – The path segment in a HTTP URL that points to a EII MUST consist of the EII’s name and if the EII is multivalue then the name MUST have the “(“ character plus the EII’s ID plus the “)” character appended onto the end.

 

3SAAD – An EII MUST be addressable using a HTTP URL path made up of the non-Web3S prefix path plus “/”plus the names of all the EII’s ancestors in order from the root down separated with “/”s plus the name of the EII itself.

 

[OPEN ISSUE – 3SAFS – Should we require support for the “.” compression trick described in the FAQ question – “Why all the long names, how come you don’t use namespaces or something in the URL to shorten the length of the URL?”]

 

net.example.articles

   net.example.article(8383)

      net.example.title

         “Manual of Surgery Volume First: General Surgery. Sixth Edition.”

      net.example.authors

         net.example.author(23455)

            org.example.firstname

               “Alexander”

            org.example.lastname

               “Miles”

         net.example.author(88828)

            org.example.firstname

               “Alexis”

            org.example.lastname

               “Thomson”

Example 8 - Articles recorded in a Web3S Infoset

If the non-Web3S prefix path is http://example.net/stuff/morestuff then we could address the lastname EII in Alexander Miles’s entry as http://example.net/stuff/morestuff/net.examples.articles/net.example.article(8383)/net.example.authors/net.example.author(23455)/org.example.lastname.

 

Although SIIs are modeled as resources they currently do not have their own URLs and therefore are addressed only in the context of EIIs. E.g. the value of an SII would be set by setting the value of its parent EII.

 

3SADY – The query segment of a HTTP URL pointing to a Web3S resource MUST be encoded using application/x-www-form-urlencoded and the names of all name/value pairs MUST be reverse DNS names.

 

3SADZ – When a Web3S resource processes the query segment of a URL addressed to it the resource MUST ignore any name/value pairs in the query segment that the Web3S resource does not recognize. If all the name/value pairs in the query segment are ignored then the resource MUST process the request as if the query segment had not been appended.

8        Web3S Content Types

8.1      Common Requirements for all MIME types

All Web3S EIIs serialized into XML will have a XML namespace with the same URI protocol – Web3SBase. If a Web3S XML MIME type contains a XML element whose namespace URI protocol isn’t Web3SBase then by definition the XML element cannot be representing Web3S infoset content.

 

Instead such elements are referred to as annotation commands. These are “decorations” of the Web3S infoset that provide instructions to the serialization processor.

 

3SAFH – If a Web3S XML serialization contains a XML element or attribute with a namespace other than “Web3SBase” then by default this XML element MUST be treated as an annotation command.

 

3SAFI - If an annotation command is not recognized by the processor of a Web3S XML MIME type that supports annotations then the unrecognized annotation command and its progeny MUST be ignored and MUST NOT be treated as members of the Web3S infoset represented by the serialization.

 

3SAFK – If an annotation command is recognized by a processor but the annotation command contains XML elements or attributes that are not recognized by the processor then the processor MUST ignore the unrecognized elements (and their progeny)/attributes.

8.1.1    Example

<foo xmlns = “Web3SBase:com.example”

     xmlns:ack=”http://foo.example.com”

     xmlns:foo=”zippy:deDoDa”>

   <ack:processPriority>

      33

   </ack:processPriority>

   <foo:somethingOdd>

      <ack:aNewThing>23</ack:aNewThing>

      <foo:go/>

   </foo:somethingOdd>

   123

</foo>

Example 9 - Application/Web3S+xml with Annotation Commands

If the previous were submitted in a Web3S XML serialization the first thing the processor would do is recognize that because processPriority and somethingOdd do not come from a Web3SBase URI protocol the XML elements must be an annotation commands.

 

Assuming the processor doesn’t recognize processPriority then the processor would act as if processPriority and its children were not present (per 3SAFI). But if the processor does recognize somethingOdd but doesn’t recognize aNewThing then the processor would treat the somethingOdd annotation command as being present but ignore the aNewThing XML element (per 3SAFK).

 

In other words the processor, when processing the previous, would ‘see’:

<foo xmlns = “Web3SBase:com.example”>

   <foo:somethingOdd>

      <foo:go/>

   </foo:somethingOdd>

   123

</foo>

Example 10 - Application/Web3S+xml after unrecognized Annotation Commands are ignored

Once the processor has applied whatever semantics are required by somethingOdd the processor would effectively remove somethingOdd and its children from the serialization and treat the remaining XML as serializing a Web3S infoset.

8.2      Application/Web3S+xml Mime Type

The Web3S infoset does not have a native serialization. When it has to be directly expressed on the wire it can only do so by using some existing serialization mechanism. In this section we define the Application/Web3S+xml MIME type. This enables a Web3S infoset to be represented using XML. This section also defines certain processing rules for dealing with unrecognized content in Application/Web3S+xml messages.

 

Document Information Items:

Property

Web3S Handling

Children

3SAAJ – The children property of the XML DII MUST NOT contain a document type declaration Information Item, MUST contain an EII and MAY contain a comment information item or processing instruction information item.

Document Element

3SAAK – The document element property of the XML DII MUST be set to the EII pointed to in the Children property.

Notations

3SAAL – The notations property of the XML DII MUST be null.

Unparsed Entities

3SAAM – The unparsed entities property of the XML DII MUST be null.

Base URI

3SAAN – The base URI property of the XML DII MUST be ignored for Web3S processing.

Character Encoding Scheme

3SAAO – The character encoding scheme property of the XML DII is for use by the XML processor and MUST be ignored for purposes of the Web3S infoset (e.g. in terms of the Web3S infoset all characters are in the abstract Unicode plane, that the character encoding scheme property was used to make that possible is an XML implementation issue).

Standalone

3SAAP – The standalone property of the XML DII MUST be set to “yes”

Version

3SAAQ – The version property of the XML DII is for use by the XML processor and MUST be ignored for purposes of the Web3S infoset.

All Declarations Processed

3SAAR – The all declarations processed property of the XML DII MUST be set to “yes” or ignored.

 

Element Information Items:

Property

Web3S Handling

Namespace Name

3SAAT – The namespace name property of an XML EII MUST be set equal to all but the last subdomain segment of the Web3S EII name prefixed with “Web3SBase:” URL scheme.

 

For example, if the Web3S EII name of an element was com.example.stuff.thing then the namespace name in XML would be “Web3SBase:com.example.stuff”.

Local name

3SAAU – The local name property of an XML EII MUST be set equal to the last subdomain segment of the Web3S EII name.

 

For example, if the Web3S EII name of an element was com.example.stuff.thing then the local name would be “thing”.

 

3SAFV – Application/Web3S+xml parsers MUST accept all EII local names in all lower case, they MAY also accept other cases if they choose.

Prefix, namespace attributes, in-scope namespaces, base URI

3SAAV – The prefix, namespace attributes, in-scope namespaces and base URI properties of an XML EII are for use by the XML processor and MUST be ignored for purposes of the Web3S infoset.

Children

3SAAW – The children property of an XML EII MUST contain either:

·        nothing,

·        only EIIs,

·        CharIIs that all MUST be presented in order, one after another and MAY contain a single Web3S ID element either before or after the CharIIs.

Attributes

3SAAX – The attributes property of an XML EII MUST be ignored for purposes of the Web3S infoset.

Parent

Maps to the Web3S EII resource’s parent.

 

Character Information Item:

Property

Web3S Handling

Character Code

3SABB – The character code property of XML CharIIs that are siblings of each other MUST be combined together to form a Web3S SII.

Element content whitespace

3SABC – The element content whitespace property of XML CharIIs MUST be honored by XML processors and used to remove non-significant whitespace CharIIs before creating Web3S SIIs.

Parent

Parent of the CharII.

 

[OPEN ISSUE – 3SAFR – White space handling in XML is, to put it kindly, tricky. For example, what happens if a Web3S client thinks that white space is treated as insignificant by default but the Web3S resource thinks otherwise? There isn’t even a standard way for the client to transmit its expectation to the Web3S resource. At least in the opposite case it is possible for the Web3S client to submit a xml:space=”preserve” value. Multi-value elements make the situation even worse. If a Web3S resource gets a PUT with <f:foo>   <web3s:ID>   abc   </web3s:ID>   Text   </f:foo> which white space is significant and which white space isn’t significant? Are the three spaces before the <web3s:ID> element significant? What about the white space around the ID? What about the whitespace between the </web3s:ID> element and Text? What about the whitespace between Text and </f:foo>? What about <f:foo>text   <web3s:ID>abc</web3s:ID>   </f:foo>? After all, nothing actually requires that the ID element go first. In that case, what white space is significant? Or, if you really want to make your head hurt what about <f:foo>   <web3s:ID>abc</web3s:ID>   </f:foo>? Is this treated as an empty multi-valued element? Is the white space significant? Which ones? All of it? Just the stuff before the ID element? Just the stuff after the ID element? It has been suggested that the easiest way to address this problem is to ban the inclusion of text in multi-valued elements. But this seems a rather draconian restriction to put on the Web3S infoset just to deal with a problem in XML. Alternatively we could require that all spaces in a Web3S serialization are significant but that would have a very serious negative effect on readability. An alternative choice is that all white space is significant inside of an EII that doesn’t contain other Web3S infoset elements. In other words, take a multi-value element like <f:foo>   <web3s:ID>abc</web3s:ID>  </f:foo>. Remove the ID element and whatever remains is significant white space, e.g. <f:foo>      </f:foo>. We can always tell when to apply the rule because we ban mixed text within the Web3S infoset.]

 

3SABI – The ID property of the Web3S EII MUST be represented in Application/Web3S+xml using the ID local name from the “Web3S:” namespace.

 

3SAAZ – The attribute information items, processing instruction information items, comment information items and namespace information items are for use by the XML processor handling the Application/Web3S+xml serialization but in all cases MUST be ignored for the purposes of the Web3S infoset.

 

3SABA – The unexpanded entity reference information items, document type declaration information items, unparsed entity information items, notation information items MUST NOT appear in Application/Web3S+xml serializations.

 

3SAEK – If an Application/Web3S+xml request is received with a Web3S infoset that violates the rules defined in this specification, for example, two sibling multi-valued EIIs have the same ID or a single valued EII has an ID, then the request MUST be rejected with a 422 Unprocessable Entity.

 

3SAEL – If an Application/Web3S+xml response is received with a Web3S infoset that violates the rules defined in this specification then the client MUST assume that the Web3S resource is suffering from a software bug and muddle through as best it can.

8.2.1    Example

com.example.namespace.DiskManagement

   com.example.namespace.DiskQuota

      com.example.namespace.MeasurementType

         com.example.namespace.Gigabytes

      com.example.namespace.Amount

         “400”

   com.example.namespace.Owners

      com.example.namespace.Owner(234234)

         com.example.namespace.OwnerID

            “tiborL”

      com.example.namespace.Owner(13234)

         com.example.namespace.OwnerID

            “Ralf”

Example 11 - A Web3S Infoset Instance to be translated to/from Application/Web3S+xml

Would translate to/from:

 

<cen:DiskManagement

                xmlns:cen = “com.example.namespace”

                xmlns:web3s = “Web3S:“>

   <cen:DiskQuota>

      <cen:MeasurementType>

         <cen:Gigabytes>

      </cen:MeasurementType>

      <cen:Amount>400</cen:Amount>

   </cen:DiskQuota>

   <cen:Owners>

      <cen:Owner>

         <web3s:ID>234234</web3s:ID>

         <cen:OwnerID>tiborL</cen:OwnerID>

      </cen:Owner>

      <cen:Owner>

         <web3s:ID>13234</web3s:ID>

         <cen:OwnerID>Ralf</cen:OwnerID>

      </cen:Owner>

   </cen:Owners>

</cen:DiskManagement>

Example 12 - An Application/Web3S+xml serialization to be translated to/from the Web3S Infoset

The previous Application/Web3S+xml example assumes that the Web3S processor has a schema that will allow it to determine significant from insignificant whitespace.

 

3SABH - When apply a schema to an Application/Web3S+xml serialization any XML element that translates to a Web3S EII that is neither explicitly allowed nor explicitly banned from appearing in the location it appears in MUST be ignored.

 

To ignore an XML element means to act as if the XML element and all of its contents do not appear in the Application/Web3S+xml serialization for the purposes of parsing the XML file. This does not mean that the element has to be physically removed from the file.

 

      <cen:Owner xmlns:e = “Web3SBase:org.example”>

         <web3s:ID>234234</web3s:ID>

         <cen:OwnerID>tiborL</cen:OwnerID>

         <e:firstname>Tibor</e:firstname>

         <e:lastname>Lukacs</e:lastname>

      </cen:Owner>

Example 13 - An Application/Web3S+xml example with extended elements

In the previous example someone has submitted a com.example.namespace.Owner EII with some extension EIIs, org.example.firstname and org.example.lastname. Assuming that these elements are not defined nor banned by the schema for com.example.namespace.Owner being used by the processor of this request the proper behavior would be to just ignore the e:firstname and e:lastname elements. E.g. pretend they are not there.

8.3      Application/Web3S+xml with Merge Semantics

On its own the Application/Web3S+xml content type is used to represent a Web3S infoset. But the semantics of that infoset can change depending on what method it is used with.

 

In the case of PUT the semantics of the Application/Web3S+xml request body are “merge the infoset information in the Application/Web3S+xml request with the infoset of the EII identified in the request-URI.” This section defines how Application/Web3S+xml is to be handled specifically in the case of PUT or any other context in which the Web3S infoset in the Application/Web3S+xml serialization is to be merged with some existing Web3S infoset.

 

Definition of Source & Destination - To increase readability this section will refer to the Application/Web3S+xml serialization with merge semantics as the ‘source’ and the Web3S infoset that the ‘source’ is to be merged into as the ‘destination’.

 

3SAFE – When applying merge semantics from a source to a destination the merge MUST occur by applying the rules in this section to the destination based on the state of the source. The source may be walked in any tree transversal order but an EII in the source MUST only be processed following the rules below if all of its ancestors have first had the rules below applied to them.

 

Implementer’s Note: The practical consequence of 3SAFE is that the requester has no idea what order the resource will use in processing a merge request. E.g. the resource is free to ignore the serialization order, can process multiple parts of the tree in parallel, etc. This approach has explicitly been chosen in order to give implementers of the destination maximum flexibility in how they apply merge semantics.

 

3SAFG – The root of the source infoset and the destination infoset MUST have the same full name or the merge MUST fail with a 422 Unprocessable entity.

 

3SAFD – If an EII encountered while walking the source does not have a matching EII in the destination that has the same location and full name then a copy of the EII and all of its children in the source MUST be made in the same location and with the same full names in the destination and the tree transversal continued. If the previous requirement cannot be met for any reason then the merge MUST fail, typically with a 422 Unprocessable entity.

 

Typical examples of why a merge might fail are that the required change violates the destination’s schema or the merge involved a multi-valued EII whose ID the destination did not wish to create.

 

For example, imagine that the source contains:

 

org.example.whatever(234)

   com.randomthirdparty.yo(efghi)

      org.example.avalue

      com.randomthirdparty.somethingElse

         “YO!!”

Example 14 - Source Web3S infoset for a merge

Now imagine that the destination, before the merge, contains:

 

org.example.whatever(234)

   com.randomthirdparty.nobodyhome

Example 15 - Destination Web3S infoset for a merge

In this example the only successful outcome of the merge would have to be:

 

org.example.whatever(234)

   com.randomthirdparty.yo(efghi)

      org.example.avalue

      com.randomthirdparty.somethingElse

         “YO!!”

   com.randomthirdparty.nobodyhome

Example 16 - Web3S infoset created after a merge

In other words, not only would all of the source’s contents have to be copied over but the full names (E.g. EII names and IDs) must also be copied over exactly. Note that the ordering of com.randomthirdparty.yo(efghi) and com.randomthirdparty.nobodyhome is irrelevant since the resulting merged Web3S infoset is unordered.

 

3SAFF – If an EII in the source does have a matching EII in the destination with the same location and full name then the action defined in the table below, which depends on the state of the EII in the source and the matching EII in the destination MUST be taken and the tree transversal continued:

Source/Destination

Empty EII

EII w/EII children

EII w/SII child

Empty EII

No Action

No Action

The SII child MUST be deleted

EII w/EII children

No Action

No Action

The SII child MUST be deleted

EII w/SII child

The  SII child from the source MUST be copied into the destination

The EII children of the destination MUST be deleted and replaced with the SII child from the source

The SII child in the destination MUST be replaced with the SII child from the source

8.3.1    Example

If the source’s state is:

com.example.a

   com.example.b

   com.example.f(1)

      com.example.g

   com.example.h(1)

      “Ork”

Example 17 - Source Web3S infoset for a merge

and the destination’s state is:

com.example.a

   com.example.b

      com.randomthirdparty.morestuff(3h23rfh23)

   com.example.f(1)

      “Eep”

   com.example.h(1)

      “Op”

Example 18 - Destination Web3S infoset for a merge

Then the processing rules would be:

Step

Source

Destination

Action

1

com.example.a

com.example.a

3SAFG: Match roots, e.g. source(com.example.a) == destination(com.example.a)

2

com.example.a/com.example.b, an Empty EII

com.example.a/com.example.b, EII w/EII children.

3SAFF: No Action

3

com.example.a/com.example.h(1), EII w/SII child

[Note: As allowed by 3SAFE, we are processing the source out of serialization order]

com.example.a/com.example.h(1), EII w/SII child

3SAFF: The SII child in the destination MUST be replaced with the SII child from the source

4

com.example.a/com.example.f(1), EII w/EII child

com.example.a/com.example.f(1), EII w/SII child

3SAFF: The SII child MUST be deleted

5

com.example.a/com.example.f(1)/com.example.g, an Empty EII

No matching EII w/same full name and location

3SAFD: create com.example.a/com.example.f(1)/com.example.g in destination

 

So the infoset of the destination after the merge would be:

com.example.a

   com.example.b

      com.randomthirdparty.morestuff(3h23rfh23)

   com.example.f(1)

      com.example.g

   com.example.h(1)

      “Ork”

Example 19 - Outcome Web3S infoset for a merge

8.4      Application/Web3SDelta+xml Mime Type

Application/Web3SDelta+xml is used to transmit a set of instructions that are to be used to update a Web3S infoset. The instructions tell the receiver what EIIs/SIIs to delete, alter or add.

 

The base format for Application/Web3SDelta+xml is the syntax and serialization used for Application/Web3S+xml with merge semantics. But Application/Web3SDelta+xml adds the delete annotation command that allows the Application/Web3SDelta+xml serialization to identify EIIs that are to be deleted. Application/Web3SDelta+xml also explicitly allows for empty IDs to be submitted for elements and for the semantics of this to mean ‘append the following new EII’.

 

3SAFC – Except as extended in this section the contents of an Application/Web3SDelta+xml serialization MUST have the same semantics as defined for Application/Web3S+xml with merge semantics.

 

3SACL – If an EII in an Application/Web3SDelta+xml serialization contains an empty ID element then the semantics of the serialization MUST be identical to having POST’ed the EII to the EII’s parent in the serialization.

 

3SABZ – The delete XML element from the Web3S: namespace is for use in the Application/Web3SDelta+xml MIME type as an annotation command. The children of the delete annotation command MUST only be XML elements.

 

3SABX – When processing a delete annotation command the contents of the command are to be treated as pointers to Web3S EIIs in the destination with the same location as the command in the source but with the full names of the command’s children. If a pointer has no matching EII in the destination then that pointer is considered to have been successfully processed. If a pointer does have a matching EII in the destination then the EII in the destination MUST be deleted or the Application/Web3SDelta+xml serialization cannot be successfully applied.

 

3SADB – Delete annotation commands MUST be processed from the root of the Application/Web3SDelta+xml file on down such that all deletes higher in the node hierarchy are processed before those lower and such that all delete annotation commands MUST be processed before applying 3SACL or Application/Web3S+xml with merge semantics.

8.4.1    Example

See the example for UPDATE.

8.5      Application/Web3SDefPage+xml Mime Type

The infosets represented by a Web3S resource can potentially be enormous. For bandwidth or CPU reasons a resource may refuse to return the full serialization of a complete infoset. By default the best the resource can do in that case is return a 511 Response Too Large. This tells the requester that the resource has refused the request because the response body is larger than the resource is willing to serialize.

 

To prevent having to return 511s a compression format of sort is needed. Application/Web3SDefPage+xml is intended to provide just such a format. This is an optional MIME type that resources may choose to support to enable them to return partial content. The Application/Web3SDefPage+xml mime type supports two annotation commands – DeferredContent and PagingContent.

 

DeferredContent tells the processor of the serialization “None of the children of the EII that contains the DeferredContent annotation command have been returned in this serialization. To retrieve them you must do a GET directly on the EII that contains the annotation command.”

 

PagingContent tells the processor of the serialization “Some of the children of the EII that contains the PagingContent annotation command have been returned in this serialization. To retrieve the rest of the children you must perform a GET on the URL provided in the body of the PagingContent annotation command.”

 

Per section 14.1 of RFC 2616 servers should not return Application/Web3SDefPage+xml MIME types unless the client explicitly indicates support for that MIME type in the accept request header.

 

Generally the proper response code for a HTTP response that contains Application/Web3SDefPage+xml is 200. 206 Partial Content is explicitly in appropriate as RFC 2616 mandates that 206 can only be returned if the request contained a HTTP Range request header.

 

Note that it is theoretically possible to use a HTTP Range request header on a request that will generate an Application/Web3SDefPage+xml response. The syntax and semantics are as defined in RFC 2616. In other words the request acts normally, the response is theoretically generated normally and then only the requested byte subset is returned. There is however no requirement that a Web3S resource support the Range HTTP request header.

8.5.1    Deferred Content

3SADT – The DeferredContent XML element from the Web3S: namespace is used as an annotation command and has no defined XML content.

 

The semantics of the DeferredContent annotation command is that the contents of the EII that the DeferredContent element is annotating have not been returned in the serialization. However the requester can always retrieve the contents directly by performing a GET on the parent EII directly.

 

3SAFL – The DeferredContent annotation command MUST NOT be a child of the application/Web3SDefPage+xml serialization’s root EII.

 

Without 3SAFL we could enter loop conditions where the root EII of the response body contains a DeferredContent that tells the requester to retrieve the same EII.

 

3SADU – If an EII includes the DeferredContent annotation command as its child in an Application/Web3SDefPage+xml message than the EII’s children from the Web3S infoset MUST NOT be serialized in the message.

 

[OPEN ISSUE - 3SAFM – Should we remove deferred content and just keep paging? See the question “Since you can clearly use paging to do anything deferred content can do why support both features?” in the FAQ for pros and cons of this issue.]

8.5.2    Paging

3SAEF – The PagingContent XML element from the Web3S: namespace is used as an annotation command and its XML contents MUST contain a string representing a URI that when used with a HTTP GET will return the next ‘page’ of contents in the current sort order, if any, using the Application/Web3SDefPage+xml serialization.

 

The semantics of placing a PagingContent annotation command as a child of an EII in an Application/Web3SDefPage+xml response is that some, possibly none, of the EII’s children have been returned but there are still more to be retrieved. In order to retrieve the next ‘page’ of results the requester will have to execute a GET request on the URI in the PagingContent annotation command.

 

The resource identified by the URI in a PagingContent annotation command is almost certainly not a Web3S resource and most likely supports no method other than GET and has no state beyond blindly returning the next ‘page’ of results. There is no need or use in submitting Web3S HTTP request headers to the resource identified in the URI as its function is very specialized.

 

3SAEH – The response to a GET on a URL returned in a PagingContent annotation command MUST be that the root EII of the response is the same as the EII that contained the PagingContent annotation. The content of the EII is then whatever portion of its children are to be returned in this page potentially along with another PagingContent annotation as a child of the root EII.

 

The client will know it has reached the last ‘page’ when there are no further page annotation commands as the child of the root of the response.

 

Resources referred to in PagingContent annotation command URLs may be very short lived so clients should be expeditious in their retrieval of their contents unless explicitly told otherwise via out of band communications with the resource.

 

There is no guarantee that the infoset returned in a GET request on a PagingContent URI will be unique. That is, the same EIIs or even slightly different versions of the same EIIs could potentially be returned in multiple pages. It is the responsibility of the requester to detect such situations.

 

The ‘pages’ returned by this protocol are generally intended to be unique to a particular request/response pair. So sharing paging URLs is not recommended.

8.5.3    Example

Imagine that a Web3S requester makes a request that returns the following Application/Web3SDefPage+xml response body:

 

GET /com.foo.bar HTTP/1.1

Host: example.com

Accept: Application/Web3S+xml, Application/Web3SDefPage+xml

 

HTTP/1.1 200 OK

<foo xmlns=”Web3SBase:com.example” xmlns:web3s=”Web3S:”>

   <bar>

      <web3s:ID>123</web3s:ID>

      <web3s:DeferredContent/>

   </bar>

   <bar>

      <web3s:ID>456</web3s:ID>

      <web3s:DeferredContent/>

   </bar>

   <bar>

      <web3s:ID>789</web3s:ID>

      <blah>

         <web3s:DeferredContent/>

      </blah>

      <icky>456</icky>

   </bar>

</foo>

Example 20 - Application/Web3SDefPage+xml example

Seeing that the caller supports Application/Web3SDefPage+xml the server choose not to return any of the infoset contents for com.example.bar(123) and com.example.bar(456). The resource did decide to return the children of com.example.bar(789) but then decided to not return the contents of com.example.blah. Any of the EIIs marked with DeferredContent can have their contents retrieved by making a GET request. E.g. http://www.example.net/com.example.foo/com.example.bar(789)/com.example.blah.

 

GET /com.foo.bar?com.live.web3s.sort=com.foo.foosort, com.foo.icksort, com.foo.racksort HTTP/1.1

Host: example.com

Accept: Application/Web3S+xml, Application/Web3SDefPage+xml

 

HTTP/1.1 200 OK

Web3sSorted = com.foo.foosort, com.foo.icksort, com.foo.racksort

 

<bar xmlns=”Web3SBase:com.foo” xmlns:web3s=”Web3S:”>

   <foo>

      <ick>

         <web3s:DeferredContent/>

      </ick>

      <bick>

         …

         <web3s:PagingContent>

            http://example.com/abcdefg

         </web3s:PagingContent>       

      </bick>

   </foo>

</bar>

Example 21 - Example of Application/Web3SDefPage+xml with both DeferredContent and PagingContent

The response includes both DeferredContent and PagingContent annotation commands. The requester can get the DeferredContent (e.g. all the children of com.foo.ick) by issuing a GET request on http://example.com/com.foo.bar/com.foo.foo/com.foo.ick. To get the PagingContent the requester will have to issue the following GET request:

 

GET /abcdefg HTTP/1.1

Host: example.com

 

HTTP/1.1 200 OK

 

<bick xmlns=”Web3SBase:com.foo” xmlns:web3s=”Web3S:”>

   <fizbang>

      <web3s:DeferredContent/>

   </fizbang>

   <foo/>

   <blah>

      …

      <web3s:PagingContent>

         http://example.com/qrstuvwxyz

      </web3s:PagingContent>

   </blah>

   <web3s:PagingContent>

      http://example.com/1234567

   </web3s:PagingContent>

</bick>

Example 22 - Example of content returned by a paging URL

This response also contains DeferredContent but now the situation is trickier. The resource that was requested, http://example.com/abcdefg is not a Web3S resource. So the requester has to know the ‘context’ of this request, that is, that the requester was asking for the children of http://example.com/com.foo.bar/com.foo.foo/com.foo.bick. Only by knowing that context information can the requester get the deferred content by making a request to http://example.com/com.foo.bar/com.foo.foo/com.foo.bick/com.foo.fizbang.

 

But, just to make things more interesting, the first page of the paging content contains two different pages. The PagingContent annotation command under com.foo.bick indicates that the enclosed URL will provide the next page of com.foo.bick’s children. But the PagingContent under com.foo.blah is new. It indicates that the returned serialization contains some of com.foo.blah’s children, but not all. In order for the requester to get a full picture of all of com.foo.bick’s children the requester is now going to have to follow two different paging ‘trails’.

 

GET /1234567 HTTP/1.1

Host: example.com

 

HTTP/1.1 200 OK

 

<bick xmlns=“Web3SBase:com.foo” xmlns:web3s=”Web3S:”>

   <ack/>

</bick>

Example 23 - Another example of paging content

This GET request returns the last page of com.foo.bick’s children. The requester knows this because the com.foo.bick XML element does not contain a PagingContent annotation. The requester will still have to make a GET request to http://example.com/qrstuvwxyz to get com.foo.blah’s children from the previous page.

9        Web3S Resources & HTTP Methods

9.1      Common Requirements For All Web3S Methods

9.1.1    Well Formed Request-URI Requirement

3SACR – If a request-URI of a HTTP request includes an EII name and either an empty ID value or no ID value but the named EII identifies a multi-valued type then the request MUST be rejected with a 403 Forbidden.

9.1.2    Optimistic Concurrency

HTTP introduced two ways to implement optimistic concurrency, date based and etag based. Originally only date based optimistic concurrency was available but this was recognized as a flawed technique due to problems with the granularity of the date values. E.g. the values only had a granularity of 1 second and many servers were able to produce numerous changes within 1 second, all of which would have the same change date.

 

To rectify this situation HTTP/1.1 introduced etags. These are opaque values that identify the state of a resource. In RFC 2616 an etag returned from a specific resource is only applicable to that resource. This specification, when dealing exclusively with Web3S resources, extends the range of resources that an etag can be applied to from just the resource that issued the etag to that resource and all of its Web3S children. This change is necessary in order to enable clients to use optimistic concurrency in regards to the state of the overall Web3S infoset. E.g. a client will want to say “Only change this leaf of the tree if the tree itself has not changed state.”

 

Implementer’s Note: RFC 2616 assumes that support for If-* headers in HTTP is mandatory on all resources for all methods.

 

3SADE – Web3S resources MAY return the Etag HTTP response header containing a strong Etag on all the methods identified below with the semantics given in the table below:

Method

Etag Semantics

GET/PUT/UPDATE

The etag identifies the state of the resource identified by the request-URI and all of its children as described in the response body.

HEAD

Same semantics as GET except there is no actual response body.

POST

The etag identifies the state of the newly created resource and all of its children as described in the response body.

 

Note that DELETE doesn’t return an etag header since etags are used to indicate ‘something’ not ‘nothing’. To make a request with the semantic “Only execute this request if the underlying resource doesn’t exist” use “if-none-match: *”.

 

3SADF – An etag issued by a Web3S resource MUST be usable on methods involving the resource the etag was issued to describe and on all of its progeny.

 

For example, requester A makes a GET request for com.example.bar and receives the etag XYZ. Later on requester A executes a PUT request on com.example.bar/com.blah.foo with an if-match header containing the etag XYZ. The Web3S resource has to be smart enough to:

·        recognize that XYZ is an etag describing the state of com.example.bar and all of its children,

·        know what state com.example.bar and its children were in when the XYZ etag was issued

·        make sure that the current state of com.example.bar and all of its children are the same as they were when XYZ was issued otherwise the request must fail with a 412 precondition failed.

 

Note however that it is completely up to the Web3S resource to decide at what granularity it will support etags.

 

 For example, imagine that requester A executes a GET request for org.different.whatever/net.someserver.someplace and gets back the etag ABC.

 

It may be that the software behind org.different.whatever is only able to generate a single etag value for the entire resource. So if any part of org.different.whatever is changed then the etag for the whole resource will change. Although this can introduce inefficiencies it cannot introduce errors.

 

Continuing the previous example, imagine that requester B comes along and issues a PUT on org.different.whatever/co.jp.cool.

 

Requester A then issues a PUT on org.different.whatever/net.someserver.someplace using the etag ABC. Requester A’s request will fail because requester B’s change, even though to a completely different part of the resource, will cause the “global” etag to change. The result is that the ABC etag is ‘out of date’ even though the part of the resource requester A wanted to change had in fact not altered since requester A executed the GET. So requester A will be forced to do a second (wasted) GET to confirm that the org.different.whatever/net.someserver.someplace’s state hasn’t changed, get the new etag and repeat the request.

 

Having such low granularity etags may be inefficient but, again, it doesn’t cause ‘errors’.

 

3SADG – The semantics of applying an etag on a method to a Web3S resource is that the method MUST only succeed if the Web3S resource the etag is rooted at (which may be any level of ancestor of the Web3S resource the method is being applied to) and all of its children are still in the same state as when the etag was issued.

 

Web3S provides no way for a requester to discover where an etag is ‘rooted’. All the requester can be sure of is that the etag is ‘good’ for at least the resource that returned it and that resource’s children.

 

3SADH – All etags generated by Web3S resources MUST be unique across all EIIs contained under the same root EII for all time.

 

In RFC 2616 etags are only meaningful in the context of a single resource. So etags only needed to be unique in the context of t