[aerogear-dev] Client Paging Strawman
Kris Borchers
kris at redhat.com
Tue Jan 15 09:01:54 EST 2013
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. 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 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
More information about the aerogear-dev
mailing list