[aerogear-dev] Client Paging Strawman

Matthias Wessendorf matzew at apache.org
Tue Jan 15 09:09:56 EST 2013


On Tue, Jan 15, 2013 at 3:01 PM, Kris Borchers <kris at redhat.com> wrote:
>
> On Jan 15, 2013, at 7:57 AM, Matthias Wessendorf <matzew at apache.org> wrote:
>
>> On Tue, Jan 15, 2013 at 2:52 PM, Kris Borchers <kris at redhat.com> wrote:
>>> Though this discussion has been great, I feel like it has headed "down a
>>> path I (JS) cannot follow". Luke, that Star Wars quote was for you. ;)
>>>
>>> When doing a read() (or next() or prev()…), I would expect the exact same
>>> type of response, which is a list of objects. This is easily accomplished in
>>> JS, we overload the read method to accept a parameter that tells it to use
>>> paging and which page to grab and then return only the results that were
>>> requested. This can then be made easier with helper functions like next(),
>>> prev(), etc. that use the overloaded read() method so the dev doesn't even
>>> need to know it exists of they don't want. This would be accomplished by
>>> maintaining the current paging state on the pipe so a call to next() just
>>> knows what to do. Also, via a couple of setter methods on the pipe instance,
>>> we can adjust the offset and limit at any time.
>>>
>>> I honestly feel like this is going to be the best developer experience on
>>> JS, I just don't know how or if it even makes sense for iOS and Java to try
>>> to get there but for JS I just can't get myself onboard with this idea of
>>> returning an object that contains next(), prev(), etc. methods instead of
>>> just the data that the user wants.
>>
>>
>> on next() a callback would be invoked, which delivers:
>> - the payload (like it does on read)
>> - the "paged result set"
>>
>> does that make sense ?
>
> Not really. All I would want returned from next() is the array of objects (payload) just as read() works.

yes

> If that changes, then I have to interact with next() differently than I would read() and that doesn't seem like a good developer experience because


how would you change the paging params? Like from "3rd next invoke, I
want to show 20, instead of 5". Hrm...Perhaps that would mean a new
"pipe" needs to be set up ?

-M

> I can just dump the result of read() into my templates for example, but I have to hang on to and further process the result from next() in your suggestion. I'm not a fan.
>>
>>
>>
>>>
>>> On Jan 15, 2013, at 7:45 AM, Sebastien Blanc <scm.blanc at gmail.com> wrote:
>>>
>>> Just to summarize what have until now :
>>>
>>> 1. Kris's proposition: https://gist.github.com/4531575
>>>
>>> 2. Summers's proposition: https://gist.github.com/4532661
>>>
>>> 3. qmx's propositon: https://gist.github.com/4538709
>>>
>>> 4. Sebi's propositionhttps://gist.github.com/4538725
>>>
>>>
>>>
>>>
>>> On Tue, Jan 15, 2013 at 2:32 PM, Matthias Wessendorf <matzew at apache.org>
>>> wrote:
>>>>
>>>> On Tue, Jan 15, 2013 at 2:25 PM, Matthias Wessendorf <matzew at apache.org>
>>>> wrote:
>>>>> I was wondering, if the result should be received on every rquest,
>>>>
>>>>
>>>> ideally on the callback..., to not block (at least in iOS land, I
>>>> would pass that "result set" on to the "success" block)
>>>>
>>>> -M
>>>>
>>>>>
>>>>> thx
>>>>>
>>>>> On Tue, Jan 15, 2013 at 2:01 PM, Sebastien Blanc <scm.blanc at gmail.com>
>>>>> wrote:
>>>>>> In the same spirit (inspired from
>>>>>>
>>>>>> http://stackoverflow.com/questions/5412059/how-to-implement-general-pagination)
>>>>>> :
>>>>>>
>>>>>>
>>>>>> public interface PagedResult<T> {
>>>>>>
>>>>>>    PagedResult<T> next();
>>>>>>
>>>>>>    PagedResult<T> prev();
>>>>>>
>>>>>>    PagedResult<T> withOffset(int offset);
>>>>>>
>>>>>>    PagedResult<T> withLimit(int limit);
>>>>>>
>>>>>>    List<T> result();
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> On Tue, Jan 15, 2013 at 1:38 PM, Douglas Campos <qmx at qmx.me> wrote:
>>>>>>>
>>>>>>> I'm not a fan of those PageContext objects (remembers me of some
>>>>>>> wild-ass
>>>>>>> ThreadLocals leaking all over)
>>>>>>>
>>>>>>> My proposal for the paging aware APIs would be something like this:
>>>>>>>
>>>>>>> public interface PagedResult<T> {
>>>>>>>
>>>>>>>    List<T> next();
>>>>>>>
>>>>>>>    List<T> prev();
>>>>>>>
>>>>>>>    List<T> page(int offset, int limit);
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> and the Async counterpart
>>>>>>>
>>>>>>> public interface AsyncPagedResult<T> {
>>>>>>>
>>>>>>>    void next(Callback<List<T>> callback);
>>>>>>>
>>>>>>>    void prev(Callback<List<T>> callback);
>>>>>>>
>>>>>>>    void page(int offset, int limit, Callback<List<T>> callback);
>>>>>>>
>>>>>>>    public static interface Callback<U> {
>>>>>>>        public void onResult(U result);
>>>>>>>    }
>>>>>>> }
>>>>>>>
>>>>>>> I don't like the idea of having a companion object for holding the
>>>>>>> pagination state.
>>>>>>>
>>>>>>> Thoughts?
>>>>>>>
>>>>>>> -- qmx
>>>>>>>
>>>>>>> On 15/01/2013, at 08:37, Matthias Wessendorf <matzew at apache.org>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi Summers,
>>>>>>>>
>>>>>>>>
>>>>>>>> https://gist.github.com/4532661
>>>>>>>>
>>>>>>>> That is a way to do paging which keeps Pipes immutable, uses
>>>>>>>> readWithFilter, and doesn't impose any (for convenient definitions
>>>>>>>> of any)
>>>>>>>> bookkeeping on the developer.
>>>>>>>>
>>>>>>>>
>>>>>>>> from your Andorid gist:
>>>>>>>>
>>>>>>>> A) Once the response has been received, the Pipe implementation will
>>>>>>>> return a List of objects. If this List instance is passed to
>>>>>>>> Pipe.getPageContext the appropriate PageContext will be returned
>>>>>>>>
>>>>>>>> Note: There is no 'return' - the readWithFilter is void, instead a
>>>>>>>> Callback is invoked (onSuccess(list)), see Pipe.java
>>>>>>>>
>>>>>>>> B) The developer will receive from readWithFilter() a List of
>>>>>>>> object. If
>>>>>>>> she passes this list into Pipe.getPageContext(List result) she will
>>>>>>>> receive
>>>>>>>> the PageContext associated with this result.
>>>>>>>>
>>>>>>>> Do you mean like:
>>>>>>>>
>>>>>>>> ...
>>>>>>>> myPipe.readWithFilter(filter, new Callback<List<Data>>() {
>>>>>>>>
>>>>>>>>
>>>>>>>> @Override
>>>>>>>>
>>>>>>>>
>>>>>>>> public void onSuccess(List<Data> data) {
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> // get the PageContext:
>>>>>>>>
>>>>>>>>
>>>>>>>> PageContext ctx = myPipe.getPageContext(data);
>>>>>>>>
>>>>>>>>
>>>>>>>> ...
>>>>>>>>
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> @Override
>>>>>>>>
>>>>>>>>
>>>>>>>> public void onFailure(Exception e) {
>>>>>>>>
>>>>>>>>
>>>>>>>> }
>>>>>>>> });
>>>>>>>> Not sure about that.....
>>>>>>>>
>>>>>>>> But for iOS I am thinking about passing in the PageContext into the
>>>>>>>> closure/block of the readWithFilter, like:
>>>>>>>>
>>>>>>>> -(void) readWithFilter:(void (^)(id<AGFilterConfig> config)) config
>>>>>>>>
>>>>>>>>
>>>>>>>> success:(void (^)(id listOfObjects, id pageContext))success
>>>>>>>>
>>>>>>>>
>>>>>>>> failure:(void (^)(NSError *error))failure;
>>>>>>>> A usage would look like:
>>>>>>>>
>>>>>>>>    [pipe readWithFilter:^(id<AGFilterConfig> config) {
>>>>>>>>
>>>>>>>>
>>>>>>>> // set the filter args and override the given defaults
>>>>>>>>
>>>>>>>>
>>>>>>>> } success:^(id listOfObjects, id pageContext) {
>>>>>>>>
>>>>>>>>
>>>>>>>> // work with the listOfObjects reponse.
>>>>>>>>
>>>>>>>>
>>>>>>>> // for paging/query info, access the given pagecontext,
>>>>>>>>
>>>>>>>>
>>>>>>>> // of the CURRENT request
>>>>>>>>
>>>>>>>>
>>>>>>>> ...
>>>>>>>>
>>>>>>>>
>>>>>>>> } failure:^(NSError *error) {
>>>>>>>>
>>>>>>>>
>>>>>>>> // handle errorz
>>>>>>>>
>>>>>>>>
>>>>>>>> }];
>>>>>>>> Any thoughts ?
>>>>>>>>
>>>>>>>> Not sure I like (or understand) the Pipe.getPageContext(List result)
>>>>>>>> call. Current mindset is that thePageContext just (and only) belongs
>>>>>>>> to the
>>>>>>>> previous (executed) request... Not sure I want to support something
>>>>>>>> like
>>>>>>>>
>>>>>>>> // first call:
>>>>>>>> List<SomeType> first;
>>>>>>>> myPipe.readWithFilter(.....) // set first inside of callback
>>>>>>>> ...
>>>>>>>> // second call:
>>>>>>>> List<SomeType> second;
>>>>>>>> myPipe.readWithFilter(.....) // set second inside of callback
>>>>>>>> ...
>>>>>>>> // third call:
>>>>>>>> List<SomeType> third;
>>>>>>>> myPipe.readWithFilter(.....) // set third inside of callback
>>>>>>>> ...
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> /// A BIT LATER ....:
>>>>>>>> myPipe.getPageContext(first);
>>>>>>>>
>>>>>>>>
>>>>>>>> I am not sure if that (myPipe.getPageContext(first);) is really
>>>>>>>> desired
>>>>>>>> (or would even easily work, as it would need to store the
>>>>>>>> "metadata").....
>>>>>>>>
>>>>>>>>
>>>>>>>> Perhaps I am just wrong.
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Matthias Wessendorf
>>>>>>>>
>>>>>>>> blog: http://matthiaswessendorf.wordpress.com/
>>>>>>>> sessions: http://www.slideshare.net/mwessendorf
>>>>>>>> twitter: http://twitter.com/mwessendorf
>>>>>>>> _______________________________________________
>>>>>>>> aerogear-dev mailing list
>>>>>>>> aerogear-dev at lists.jboss.org
>>>>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> aerogear-dev mailing list
>>>>>>> aerogear-dev at lists.jboss.org
>>>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> aerogear-dev mailing list
>>>>>> aerogear-dev at lists.jboss.org
>>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Matthias Wessendorf
>>>>>
>>>>> blog: http://matthiaswessendorf.wordpress.com/
>>>>> sessions: http://www.slideshare.net/mwessendorf
>>>>> twitter: http://twitter.com/mwessendorf
>>>>
>>>>
>>>>
>>>> --
>>>> Matthias Wessendorf
>>>>
>>>> blog: http://matthiaswessendorf.wordpress.com/
>>>> sessions: http://www.slideshare.net/mwessendorf
>>>> twitter: http://twitter.com/mwessendorf
>>>> _______________________________________________
>>>> aerogear-dev mailing list
>>>> aerogear-dev at lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>
>>>
>>> _______________________________________________
>>> aerogear-dev mailing list
>>> aerogear-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>
>>>
>>>
>>> _______________________________________________
>>> aerogear-dev mailing list
>>> aerogear-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>>>
>>
>>
>>
>> --
>> Matthias Wessendorf
>>
>> blog: http://matthiaswessendorf.wordpress.com/
>> sessions: http://www.slideshare.net/mwessendorf
>> twitter: http://twitter.com/mwessendorf
>>
>> _______________________________________________
>> aerogear-dev mailing list
>> aerogear-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
>
>
> _______________________________________________
> aerogear-dev mailing list
> aerogear-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/aerogear-dev



-- 
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf



More information about the aerogear-dev mailing list