[Grok-dev] Re: Is there an easy way to customize URL used for grok.REST (use suffix instead of prefix) ?

Craeg Strong cstrong at arielpartners.com
Mon Jun 2 11:00:08 EDT 2008


Martijn Faassen wrote:
> Craeg Strong wrote:
>> I would like to use simple relative URLs in my javascript like 'xml'
>>
>> But I am having trouble figuring out how to marry grok.Traverser with 
>> grok.REST.
>>
>> Can anyone provide a bread crumb for me to follow?
>
> You could see this as partitioning your resource space. Some resources 
> (you call it 'xml') are REST-only, others are non-REST.
Yes, that is exactly what I am doing.   That is a compromise position 
that is easier for command line tools like curl to deal with.

In the future I would like to try making the *same* URL support both an 
HTML View and an XML "View" via content negotiation.
That was the original vision (as I understand it) for REST, and it would 
be great if Grok made that easy to do.

I hope I could do that by having two different adapters for my 
container, one for HTML and one for REST and somehow signal to the zope3
infrastructure to dispatch to the correct one depending on whether Grok 
receives:

    Content-type: text/html

or

    Content-type: text/xml

in the Request.  The text/html would automatically use my grok.View zope 
page template to serve up HTML, and the text/xml would automatically 
delegate to my grok.REST subclass instance. 

By partitioning the URL space with 'xml', I am in effect encoding the 
content type in the URL, which is a REST no-no, but a very convenient 
and I suspect widely practiced work around :-)
> You could accomplish something like this by using traversing behavior 
> (you can use a custom grok.Traverser on an interface to make this more 
> universal):
>
> class MyContainer(grok.Container):
>     def traverse(self, name):
>         if name == 'xml':
>             return ContainerXml(self)
>
> class ContainerXml(grok.Model):
>     def __init__(self, context):
>         self.context = context
>
> @grok.subscribe(ContainerXml, IBeforeTraverseEvent)
> def restSkin(obj, event):
>    ... apply the rest skin
>
> You then attach your REST view to ContainerXml, which can talk to the 
> container through its context.
Cool!   I am sorry to be so dense, but is the "...apply the rest skin" 
where I return a new instance of my grok.REST subclass?
I admit I have not yet grasped the full zen of IRESTLayer, REST, 
RESTProtocol, etc. 

That is, I am in a position I expect is common for experienced 
developers discovering a powerful new technology. 
I understand what the above classes represent in an abstract sense,
and I know that applying them in any given use case in grok should take 
only a few lines of code,
and I know that my brute force efforts are not the correct way to do it,
but I do not know the certain three lines of code that will actually 
make it work. :-)

That is another reason I want to get PyDev/Eclipse working for debugging 
my zope3/grok instance, so I can actually trace code paths to see what 
is really going on (see other email thread).
> If this pattern is common enough, we might want to abstract this whole 
> pattern out into something like a 'RelativeRestResource' or something. 
> I can imagine people would want something similar for JSON and XMLRPC 
> as well, though it's less important to keep the URL spaces separate in 
> that case.
Yes, something like that which also incorporates my other use case 
described above would be fantastic!
I am way too much of a newbie to contribute code, but can contribute the 
writing and executing of tests and documentation.

--Craeg


More information about the Grok-dev mailing list