added XmlFileHandler to exyus

2007-08-17 @ 23:18#

this evening i implemented a simple XmlFileHandler for the exyus framework. it didn't take much time and really made sense. i mean, POST/GET/PUT/DELETE for xml documents is basic, right? cool thing is, since i'm using the base classes from exyus, the caching details are already baked in.

i had a bit of pause when i came to deciding on the exact behavior for POST and PUT. i decided to stick with POST for create and PUT for update. that means the server generates the URI id for each POST (if the user named the URI, the PUT would be the way to go). this follows the SqlXmlHandler pattern, too. since the server is generating the URI id, i am currently using UUIDs for the id. not pretty, but easy. i might want to change that in the future and go with user-named documents using PUT. treat it more like a document system, i guess.

handling the document listing (GET /documents/) was also a bit of a challenge. i decided to use the file system to generate an index of all the documents in the storage location (a single folder) and use that to create a simple XML document that i keep in memory. i also use XSLT to transform the file list document using the XSLT documents() function to build up a custom output document. this may be a bit too much trundling about for the final product, but i'll give it some time to work itself out. since the resulting document is placed in the local cache (until an update invalidates it), the scaling cost for simple apps should be minimal.

so ok, here's what it looks like for me to define a "user" resource using the XmlFileHandler:

// example xmlfile handler [UrlPattern(@"/users/?(.*).xcs\??(.*)$")] public class userFile : XmlFileHandler { public userFile() { this.LocationUri = "/users"; this.UrlPattern = @"/users/?(.*).xcs\??(.*)$"; this.DocumentsFolder = "~/documents/users/"; this.StorageFolder = "~/storage/users/"; this.XHtmlNodes = new string[] { "//notes" }; this.LocalMaxAge = 600; this.ImmediateCacheUri = new string[] { "/users/", "/users/{@id}" }; } }


i changed the URI id generator from UUID to a HEX version of the timestamp. while the representaiton is still kinda gnarly (x8c9af6fdb361290), it's still better than a UUID (CA5047D3-9504-47DC-95B0-5FEC82234A98). note i add an 'x' to the front of the hex value to make sure it's a valid XML label, too.

i'm thinking more seriously about supporting PUT w/ a unique ID from the client. that will require proper handling of ETag & If-Match/If-None-Match or Last-Modified & If-Modified/If-Not-Modified headers. something i should be doing anyway...