{"id":10,"date":"2006-06-08T21:24:53","date_gmt":"2006-06-08T21:24:53","guid":{"rendered":"http:\/\/robubu.com\/?p=10"},"modified":"2006-06-08T21:29:05","modified_gmt":"2006-06-08T21:29:05","slug":"cardatom","status":"publish","type":"post","link":"https:\/\/robubu.com\/?p=10","title":{"rendered":"Sorting and Filtering in Atom &#8211; CardAtom"},"content":{"rendered":"<p>So <a href=\"http:\/\/robubu.com\/?p=9\">CalAtom<\/a> can get kind of complicated when it comes to querying, so before tackling the querying in that properly (I think what we have proposed to date needs a lot more work) I wanted to first see if the querying \/ sorting required for CardAtom could be accomplished. CardAtom would be an attempt to remote an api for managing contacts in an address book. It would store, update and manipulate collections of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Vcard\">vCards<\/a> via the Atom Publishing Protocol. The CRUD operations would be identical to those described in CalAtom only with vCard payloads (see the early slides in <a href=\"http:\/\/robubu.com\/CalAtom\/CalAtom.html\">this CalAtom presentation<\/a> for details on how this can work). While this works, APP is presently limited to always returning the entire collection and doing so in last modified order.\u00c2\u00a0 So how should sorting and filtering be accomplished in APP. We&#8217;ll take these one at a time.<\/p>\n<p><strong>Sorting<\/strong><\/p>\n<p>The <a href=\"http:\/\/www.ietf.org\/internet-drafts\/draft-ietf-atompub-protocol-08.txt\">atom publishing protocol<\/a> mandates the collection order to be by last modified date. This is not that useful to a CardAtom client that wants to display the collection by familyname or givenname. The client could download the entire collection and then do local sorting, but as the number of contacts increases this becomes less and less viable. <\/p>\n<p>Servers can produce collections in any order and make these alternative sort orders available via a url, the only tricky bit is communicating their existence and location to the client. This can, however, be accomplished by placing the sort order&#8217;s url in a link element within the original feed. The links &quot;rel&quot; attribute is used to indicate the particular sort order available at the url. So the feed for the vCard collection now looks like this.<\/p>\n<p><code><br \/>\n&lt;feed xmlns=\"http:\/\/www.w3.org\/2005\/Atom\"&gt;<br \/>\n &lt;title type=\"text\"&gt;rob's contacts&lt;\/title&gt;<br \/>\n &lt;updated&gt;2005-07-31T12:29:29Z&lt;\/updated&gt;<br \/>\n &lt;id&gt;tag:example.org,2003:3&lt;\/id&gt;<br \/>\n &lt;link rel=\"self\" type=\"application\/atom+xml\"<br \/>\n  href=\"http:\/\/example.org\/contacts\" \/&gt;<br \/>\n <span style=\"color: green\">&lt;link<br \/>\n   rel=\"http:\/\/purl.org\/CardAtom\/sort\/byFamilyName\/asc\"<br \/>\n   type=\"application\/atom+xml\"<br \/>\n   title=\"by Family Name\"<br \/>\n   href=\"http:\/\/example.org\/contacts\/byFamilyName\"\/&gt;<\/span><br \/>\n &lt;entry&gt;<br \/>\n  &lt;title&gt;Rob Yates&lt;\/title&gt;<br \/>\n  &lt;summary type=\"html\"&gt;<br \/>\n  &amp;lt;p&gt;&amp;lt;strong&gt;Tel:&amp;lt;\/strong&gt;+1-234-567-8901&amp;lt;\/p&gt;<br \/>\n  &lt;\/summary&gt;<br \/>\n  &lt;link rel=\"edit-media\" type=\"text\/directory\" href=\"http:\/\/example.org\/contact\/1\"\/&gt;<br \/>\n  &lt;id&gt;tag:example.org,2003:3.2397&lt;\/id&gt;<br \/>\n  &lt;updated&gt;2005-07-31T12:29:29Z&lt;\/updated&gt;<br \/>\n  &lt;content src=\"http:\/\/example.org\/contact\/1\"  type=\"text\/directory\" \/&gt;<br \/>\n &lt;\/entry&gt;<br \/>\n &lt;entry&gt;  .....<br \/>\n&lt;\/feed&gt;<br \/>\n<\/code><\/p>\n<p align=\"left\">Note that this uses the fact that link\/@rel (as defined by <a href=\"http:\/\/www.ietf.org\/rfc\/rfc4287.txt\">atom<\/a>) can actually take any arbitrary url to define its meaning. A CardAtom specification could therefore define a set of link relationships that define the mandatory and optional sorts that a CardAtom collection supports. A client reading the feed can search for a particular sort order using the value of link\/@rel and if it wants to render the collection in that order it can simply retrieve the corresponding urls contents, nice. <\/p>\n<p align=\"left\">I can also imagine &quot;standard&quot; sort orders being defined by specific &quot;rel&quot; values, e.g. &quot;by Title&quot; or &quot;by Author Name&quot;.<\/p>\n<p><strong>Filtering<\/strong><\/p>\n<p>Filtering is much trickier. How does the server communicate to the client the searches\/filters that it supports. The server could allow for very flexible and complex queries to be written in which case something like <a href=\"http:\/\/www.w3.org\/TR\/xquery\/\">XQuery<\/a> or <a href=\"http:\/\/www.w3.org\/TR\/rdf-sparql-query\/\">SPARQL<\/a> should be used. While extremely flexible, the problem with those is that the server MUST allow any attribute to be searched and this dramatically increases both the cost of implementation and the subsequent optimizations. For CardAtom it seems that we really only need to support full text searches as well as filtering by FamilyName and GivenName. We just need a way to describe these options to the client, and so it was that <a href=\"http:\/\/www.snellspace.com\/wp\/index.php\">James<\/a> reminded me of <a href=\"http:\/\/opensearch.a9.com\/\">A9&#8217;s opensearch<\/a>. Opensearch contains a <a href=\"http:\/\/opensearch.a9.com\/spec\/1.1\/description\/\">description document<\/a> that describes a search supported by the site. For CardAtom we want to offer a full text search, a familyName search and a givenName search. First off here is one that describes the full text search.<\/p>\n<p><code><br \/>\n&lt;OpenSearchDescription xmlns=\"http:\/\/a9.com\/-\/spec\/opensearch\/1.1\/\"&gt;<br \/>\n &lt;ShortName&gt;Search&lt;\/ShortName&gt;<br \/>\n &lt;Description&gt;Search the contact store&lt;\/Description&gt;<br \/>\n &lt;Url type=\"application\/atom+xml\"<br \/>\n  template=\"http:\/\/example.org\/contacts?q={searchTerms}\/&gt;<br \/>\n&lt;\/OpenSearchDescription&gt;<br \/>\n<\/code><\/p>\n<p>note that {searchTerms} in the url above defines where a substitution should be made.\u00c2\u00a0 Opensearch also defines the meaning of &quot;searchTerms&quot;.\u00c2\u00a0 Then here&#8217;s the familyName search.<\/p>\n<p><code><br \/>\n&lt;OpenSearchDescription xmlns=\"http:\/\/a9.com\/-\/spec\/opensearch\/1.1\/\"<br \/>\n xmlns:xcard=\"http:\/\/www.ietf.org\/internet-drafts\/draft-dawson-vCard-xml-dtd-<br \/>\n   04.txt\"&gt;<br \/>\n &lt;ShortName&gt;by Family Name&lt;\/ShortName&gt;<br \/>\n &lt;Description&gt;Search the contact store for a given family name&lt;\/Description&gt;<br \/>\n &lt;Url type=\"application\/atom+xml\"<br \/>\n  template=\"http:\/\/example.org\/contacts?familyName={xcard:family}\/&gt;<br \/>\n&lt;\/OpenSearchDescription&gt;<br \/>\n<\/code><\/p>\n<p>Note that this one uses the <a href=\"http:\/\/www.watersprings.org\/pub\/id\/draft-dawson-vcard-xml-dtd-03.txt\">xCard<\/a> namespace to indicate that the substitution variable should be of type &lt;family&gt; as described in the xCard specification.<\/p>\n<p>And so, if we make these two description files available at an appropriate location we can now link to those in the feed as well (although I only show one for brevity), e.g.<\/p>\n<p><code><br \/>\n&lt;feed xmlns=\"http:\/\/www.w3.org\/2005\/Atom\"&gt;<br \/>\n &lt;title type=\"text\"&gt;rob's contacts&lt;\/title&gt;<br \/>\n &lt;updated&gt;2005-07-31T12:29:29Z&lt;\/updated&gt;<br \/>\n &lt;id&gt;tag:example.org,2003:3&lt;\/id&gt;<br \/>\n &lt;link rel=\"self\" type=\"application\/atom+xml\"<br \/>\n  href=\"http:\/\/example.org\/contacts\" \/&gt;<br \/>\n <span style=\"color: green\">&lt;link<br \/>\n   rel=\"http:\/\/purl.org\/CardAtom\/sort\/byFamilyName\/asc\"<br \/>\n   type=\"application\/atom+xml\"<br \/>\n   title=\"by Family Name\"<br \/>\n   href=\"http:\/\/example.org\/contacts\/byFamilyName\"\/&gt;<\/span><br \/>\n <span style=\"color: blue\">&lt;link<br \/>\n   rel=\"http:\/\/purl.org\/CardAtom\/search\/byFamilyName\"<br \/>\n   type=\"application\/opensearchdescription+xml\"<br \/>\n   href=\"http:\/\/example.org\/contacts\/search\/byFamilyName\"\/&gt;<\/span><br \/>\n &lt;entry&gt;<br \/>\n  &lt;title&gt;Rob Yates&lt;\/title&gt;<br \/>\n  &lt;summary type=\"html\"&gt;<br \/>\n  &amp;lt;p&gt;&amp;lt;strong&gt;Tel:&amp;lt;\/strong&gt;+1-234-567-8901&amp;lt;\/p&gt;<br \/>\n  &lt;\/summary&gt;<br \/>\n  &lt;link rel=\"edit-media\" type=\"text\/directory\" href=\"http:\/\/example.org\/contact\/1\"\/&gt;<br \/>\n  &lt;id&gt;tag:example.org,2003:3.2397&lt;\/id&gt;<br \/>\n  &lt;updated&gt;2005-07-31T12:29:29Z&lt;\/updated&gt;<br \/>\n  &lt;content src=\"http:\/\/example.org\/contact\/1\"  type=\"text\/directory\" \/&gt;<br \/>\n &lt;\/entry&gt;<br \/>\n &lt;entry&gt;  .....<br \/>\n&lt;\/feed&gt;<br \/>\n<\/code><\/p>\n<p>So this seems to all be working, although we haven&#8217;t coded it yet :).\u00c2\u00a0 The feed\/collection describes its alternate sort orders and its possible filters and how to invoke them. <\/p>\n<p>One thing that I think still needs further thought though is whether these sort or search\/filter links are discoverable outside of the collection document.\u00c2\u00a0 It seems wrong that a client must first load a collection with the default sort order only to locate the sort order that it actually wants to use\u00c2\u00a0 Should there be an introspection document per collection that can somehow be retrieved from the collection url?\u00c2\u00a0 Maybe a GET against the collection url with an accept header of &quot;application\/atomserv+xml&quot;, not sure&#8230;<\/p>\n<p>\u00c2\u00a0I welcome suggestions for improvements or alternative approaches, these are features that as we use Atom for more things it seems like we need. Once the core spec is complete I hope these are considerations for the working group.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So CalAtom can get kind of complicated when it comes to querying, so before tackling the querying in that properly (I think what we have proposed to date needs a lot more work) I wanted to first see if the querying \/ sorting required for CardAtom could be accomplished. CardAtom would be an attempt to &hellip; <a href=\"https:\/\/robubu.com\/?p=10\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Sorting and Filtering in Atom &#8211; CardAtom&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[2],"tags":[],"class_list":["post-10","post","type-post","status-publish","format-standard","hentry","category-atom"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/robubu.com\/index.php?rest_route=\/wp\/v2\/posts\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/robubu.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/robubu.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/robubu.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/robubu.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10"}],"version-history":[{"count":0,"href":"https:\/\/robubu.com\/index.php?rest_route=\/wp\/v2\/posts\/10\/revisions"}],"wp:attachment":[{"href":"https:\/\/robubu.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/robubu.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/robubu.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}