launchpad-dev team mailing list archive
-
launchpad-dev team
-
Mailing list archive
-
Message #01686
Re: Redesigning lazr.restful support for AJAX
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.
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?
Attachment:
signature.asc
Description: PGP signature
Follow ups
References