Resource as Avatar (was Re: [Twisted-web] newbiew question)

Phil Mayers p.mayers at imperial.ac.uk
Wed Jul 23 10:13:49 EDT 2008


>> The information about the user does not belong in any Resource subclass: a
>> Resource is a page that can be generated for different users, so it should
>> only contain information that is the same for all users. Any user specific
>> data should be fetched via the request object.
> 
> This is totally inaccurate. It's perfectly reasonable to store
> user-specific data in Resource objects.  "a Resource is a page that
> can be generated for different users" is either irrelevant or not
> true, I can't tell which. You can dynamically and return Resources
> based on which user is making the request.
> 
> Now, I'm not sure my favorite abstraction for a user is a string; I'd
> probably pass something other than a username to a Resource. Perhaps a
> rich object representing the user.
> 
> 

Since this is a common mis-conception (one I suffered from and have now 
disabused myself of) it's worth discussing.

If my understanding is correct: twisted.cred uses the concept of an 
"avatar". Avatars (I think...):

  * are protocol objects
  * represent the user

In twisted.web, the Resource *is* the avatar. In twisted.mail.imap, the 
Mailbox is the avatar. In twisted.conch, the Shell is the avatar (and so 
on).

I found this initially confusing, because in many web frameworks e.g. 
Zope, where I came from, the objects representing resources are:

  * long lived
  * the same instances serve >1 HTTP request
  * instantiated at process start time

It's also somewhat confusing because unlike other protocols, HTTP 
requests are very short-lived. It's worth noting you *can* have 
long-lived multi-instance t.w.Resource objects.

In twisted, a common design pattern seems to be (I hope; I adopted it...)

  * have your realm return a root Resource i.e. one for "/"
  * attach your User object to that resource
  * have your root resource dynamically create the leaf resources via 
locateChild or childFactory, then attach the User object
  * when you need user info, get at it via e.g. self.user
  * let the leaf/root objects get GC-ed when the HTTP request is done

I believe changes have been committed to twisted.web making this design 
pattern even more preferred:

http://twistedmatrix.com/trac/changeset/23950

Code which, by the way, I very much like the look of.

Could someone clarify if this is the "right" way of doing things?



More information about the Twisted-web mailing list