← Back to team overview

launchpad-dev team mailing list archive

Re: Redesigning lazr.restful support for AJAX

 

On November 18, 2009, Gavin Panella wrote:
> On Wed, 18 Nov 2009 14:06:43 -0500
> 
> "Francis J. Lacoste" <francis.lacoste@xxxxxxxxxxxxx> wrote:
> > On November 18, 2009, Maris Fogels wrote:
> > > On 09-11-16 06:06 PM, Francis J. Lacoste wrote:
> > > > 1) We want to be able to retrieve one or multiple page fragments
> > > > after making a model change through the web service (either PATCH or
> > > > named operation).
> > > >
> > > >    (For example, subscribing a user means that maybe two or three
> > > > parts of the page will need to be updated.)
> > >
> > > Does anyone have any other examples of when this would be useful?
> >
> > Adding a team member inline requires updating three or four parts of the
> > page. (Salgado and Bjorn have the details).
> >
> > It's a pretty common pattern.
> >
> > > > 2) We want to reuse the presentation logic already coded in the
> > > > regular web UI views.
> > > >
> > > >    (We already have views that know how to render the different parts
> > > > that needs to be updated on the page.)
> > > >
> > > > 3) We want to provide a very productive API for front-end developers
> > > > to use. (Minimize amount of web-service specific glue needed,
> > > > minimize the amount of confusing asynchronous requests that needs to
> > > > be done).
> > > >
> > > > So one solution we found out was to basically drop the way HTML
> > > > representation are currently implemented for something much simpler
> > > > and much more powerful.
> > > >
> > > > Instead of wiring server-side one-to-one individual web-service
> > > > resources to an HTML representation, we should basically let the AJAX
> > > > client decide what should be returned from the web service call.
> > > >
> > > > The client would request that one or more views be rendered after the
> > > > successful completion of the API call and their results returned to
> > > > the client.
> > > >
> > > > We could use the accept-extension to the Accept header to specify the
> > > > list of views to return results.
> > > >
> > > > Something like:
> > > >
> > > > Accept:
> > > > application/x-page-fragments;views="subscribers=+subscriber-portlets,
> > > > count=+subscribers-count"
> > > >
> > > > That should return a JSON dictionary containing two keys: subscribers
> > > > containing the result of the +subscriber-porlets view and count
> > > > containing the result of the +subscribers-count view.
> > > >
> > > > That removes the wiring that has to be done now server side to map
> > > > these existing views to the HTML representation of fields, removes
> > > > the problematic limitation of having only HTML representation and
> > > > allows us to retrieve efficiently all the fragments we need on the
> > > > page.
> > >
> > > I assume you are calling the webservice as you would normally, but you
> > > are adding your special Accept header?
> >
> > Yes, the idea is that the client controls the result part.
> >
> > > If that is the case, then it still feels a bit strange.  You are taking
> > > the API model and namespace, and mapping that onto a set of page
> > > fragment names. However, this set of fragments actually represents the
> > > Launchpad website URL model, not the API model.  You are telling the
> > > webservice "Get me a bug comment, but using this magic word, return it
> > > to me as >  it would appear on the page at /+bugs/1234/."
> >
> > A fragment is a view.
> >
> > The common use case is not 'Get me a bug comment', but 'Create a bug
> > comment and give me the result formatted through '@@bug-comment-details'.
> >
> > Or 'Subscribe this user' and gave me back '@@+portlet-subscribers,
> > @@subscribers-count'.
> 
> If we expect each widget to know what page fragments to update it'll
> become a tight bundle of spaghetti pretty quickly, especially if a
> widget it used on more than one page.
> 
> Could the following pattern (probably has a name, but I don't know it)
> help avoid it, such that a widget A doesn't have to care about the
> presence or absence of widget B?
> 
> widget A is going to add a subscriber,
> widget A says to client api machinery:
>     "add subscriber, and get me +subscriber-fragment",
> widget B see this, is interested in subscriber changes,
> widget B says to client api machinery:
>     "count me in, get +subscriber-xyz for me too",
> client api machinery sends request to launchpad:
>     "add subscriber, get +subscriber-fragment, +subscriber-xyz"
> client api machinery dispatches results to widget A and widget B.
> 

That would be a very nice addition. But I wouldn't implement that in the first 
iteration. Just to see if the nightmare happens first.

> ISTR that Christian Heilmann spoke of something like this at the Epic?
> 
> > > If you want a real loop, look at it this way:  you map the database
> > > model to the webservice WADL addresses, and you map the database model
> > > to the website URL addresses.  URLs are rendered by views.  OK.  We are
> > > suggesting that views are also rendered by Fragment Names.  Also OK. 
> > > But then we are say that to call the Fragment Name, you have to know
> > > the correct address, and that address is an object picked out of the
> > > WADL? Why not use the address you already have, that being the URL of
> > > the page you are currently visiting?
> >
> > I think that we should allow both absolute and relative URLs to be
> > specified. In the common case, the view will be found on the target
> > object, but something, the HTML you are interested is form a subobject or
> > the parent. So we should support both relative and absolute paths.
> >
> > > Instead of mapping one namespace onto the other, could we just call the
> > >  current page address to fetch the fragment?
> > >  Y.io("?fragment=A&fragment=B").  I guess this is the +fragments
> > > solution Aaron pointed to?  What exactly are the problems with it?
> >
> > I don't understand what you are saying. This solution is exactly the same
> > than what Aaron was suggesting, but using passing the views you want to
> 
> I /think/ he meant, why not use the same ingress point to the
> application as other web pages, rather than piping through the API?
> 

Because you are already making an API call.


-- 
Francis J. Lacoste
francis.lacoste@xxxxxxxxxxxxx

Attachment: signature.asc
Description: This is a digitally signed message part.


References