← Back to team overview

launchpad-dev team mailing list archive

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