Closed (fixed)
Project:
JSON:API
Version:
8.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
11 Jun 2016 at 09:50 UTC
Updated:
7 Jul 2017 at 05:45 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
e0ipsoThis was way more complex than anticipated :-/
This patch contains some refactoring that is totally out of scope for the current task, but I don't want to invest the time to extract to a different pacth, …
Cheers.
Comment #5
e0ipsoThis also contains the code from #2742763: [FEATURE] Add support for pagination. So setting as blocked until that gets in.
Comment #6
e0ipsoRe-rolling after #2742763: [FEATURE] Add support for pagination was merged. Also fixes some white space stuff.
Comment #7
e0ipsoComment #10
e0ipsoComment #13
dawehnerI'm wondering whether there are many usecases to go to the last page rather than just to the next one. If you limit to have just one additional page you can get rid of the often really expensive count query by fetching N+1 items and show a next link in case there is a (N+1)th result.
Comment #14
e0ipsoThat is a very good idea @dawehner. I'll work on that in the morning.
I'm reuploading the previous patch to kick off the tests again.
Comment #15
e0ipsoComment #16
e0ipsoAlso, @dawehner do you think that knowing the number of pages for a list is not critical?
Comment #19
dawehnerWell, for a classical desktop application this might be, but for most mobile applications you don't have pagers where you need to click, but rather have some sort of scrolling, or at least just a next button. A classical pager is hard to use on a phone. One thing I consider an important feature is the use of a total count, but this is not needed for every application. Can we somehow add an option to include the total amount of items, when people want to? In which case we have the total number, we could expose the last link, as it doesn't cost us much more.
This was just me thinking out loud for a while.
Comment #20
e0ipso@dawehner I'm only asking because I've always been undecided with this. It's a pretty heavy tradeoff between feature and performance. I'll keep both patches on the lease for now so we can decide later.
Comment #21
dawehnerCool, yeah of course. In core we decided to go with minipagers by default, so sites scaling up don't run into issues at some point.
Comment #22
e0ipsoThe current patch removes the extra
COUNTquery. I like this approach better!Comment #23
dawehnerLet's ensure to not remove that when we commit
We should document when to use this setter. This seems not entirely obvious
What about using really simply
Url::fromRoute('<current>', [], ['query' => $query])In that case we don't even have to pass along the request.In those cases I always use
max($offset - $size, 0);Nitpick: isn't $offset defaulting to 0 already due to the function signature? The fallback and the isset() here disagree a bit though
this could be interesting
Comment #24
e0ipsoI'll make sure to follow up tomorrow morning.
Comment #25
e0ipsoComment #26
dawehnerAh I see, fair point!
I would kinda prefer clean code over clean unit tests to be honest :) Feel free to keep it of course!
Comment #27
e0ipsoAdded feedback. Interdiff is not terribly accurate since I had to resolve upstream merge conflicts.
Comment #28
e0ipsoComment #29
e0ipsoYet another re-roll.
Let's try to merge this soon so we can avoid (time consuming) re-rolls.
Comment #32
dawehnerSure, let's just commit it, once we have a green patch :)
Comment #33
e0ipsoGive it a go testbot!
Comment #35
dawehnerThank you @e0ipso!
Thank you testbot!
Comment #37
dubcanada commentedI disagree with #19. While having standard (<< First < Prev 1 2 3 4 5 Next> Last >>) pagination on mobile is not used very often. Any other interface (web, desktop for example) always has pagination with a last button, and multiple pages (<< First < Prev 1 2 3 4 5 Next > Last >>) type interfaces. There are also times on mobile where you want to know the number of items (showing 10 out of 150 products).
Also the JSON spec says the api must return a last link.
If this is a performance issue, is there a way to do the query while ignoring aspects (for example you don't need to consider include, and sort while getting the count), ideally you would just want a SELECT COUNT(*) FROM table WHERE filter/conditions. Filtering and conditions sometimes requires joining, but the database is very good at that. This count number can also be cached. Views already murders the database, I doubt jsonapi counts would add much on top.
Do you guys have any performance differences between having the count there and doing just the N+1?
Comment #38
dubcanada commentedAdded a patch to add last link back in. It's based on the original patch above. If you want to test performance in src/Controller/EntityResource.php you can comment line 268 and add $total_results = 0;
Doing some very basic tests (100 entities with a single filter and includes/sort) the difference is around 15-20 ms on a $5 digital ocean box uncached. Once it is cached (second call) it's 0 to 5 ms.
Ideally I think it should be re-added, it adds consistency with the json api spec.
I'd also like the see the total_count exposed in some sort of meta way, so people can do things like (showing 10 of 153 products) and stuff like that.
If you want me to add in the tests (this patch is missing them) let me know and I will.
Comment #39
SlayJay commented@dubcanada just as an FYI there is a hard coded limit of 50 results per request in the json api module.
So doing your tests against 100 entities might be misleading.
( see issue: https://www.drupal.org/node/2793233 )
Comment #40
e0ipsoThis should be added as an optional (opt-in) extension instead of adding it for everyone.
Comment #41
dubcanada commented@e0ipso should we add this to json_extras? I'm not sure how best to proceed with this. Or maybe just a module within jsonapi?
Ideally we could expose all pagination meta data, including total results, etc, not just last page link.
Comment #42
e0ipsoRelated #2877041: Provide the query count
Comment #43
gun_dose commented@dubcanada I found one mistake in your patch - in [offset] it returned page number instead of count of items that must be skipped. So I attached fixed patch to my comment
Comment #44
gun_dose commented@dubcanada, I found one more error in your patch and fixed it in attached file
Comment #45
spleshkaSending the patch to automated testing.
Comment #49
sluceroThe attached patch builds on top of the existing patch work from #2746939-44: [FEATURE] Add pagination metadata to expose the already calculated result count to the meta section as discussed in #2877041: Provide the query count.
Comment #50
spleshkaBeing the "test launcher" guy the second time in this issue :P
Comment #52
dpolant commentedUpdated patch to fix a couple failures:
1) In queries using operator grouping such as the test running around line ~173 in Drupal\Tests\jsonapi\Functional\JsonApiFunctionalTest::testRead(), it was possible for options to bleed over into subsequent queries using the same query builder object. I fixed this by wiping the options property at the beginning of Drupal\jsonapi\Query\QueryBuilder::newQuery().
2) I updated the link manager test expectations to account for the total count and last page properties.
Comment #53
e0ipsoI agree on the implementation, however this feature has an impact on performance. That's why we proposed to move it to JSON API Extras and make it opt-in, see #2877041: Provide the query count.
Anyone opposes to move this to JSON API Extras? I acknowledge that it's going to be more complicated to do it from there, but I think performance is key.
Comment #54
dpolant commentedHere is the plan for this feature per our conversation in #contenta:
1) ResourceType has a method called "includePageCount()" that returns FALSE always.
2) ConfigurableResourceType overwrites that "includePageCount()" and reads from a global configuration option in jsonapi_extras (like the prefix option).
#1 can be done in jsonapi and tracked on this ticket, #2 needs to be in jsonapi extras (https://www.drupal.org/node/2877041)
Comment #55
dpolant commentedThe patch attached here gates the include count and "last" meta stuff behind an includeCount method on the resource type.
The tests are passing, but someone should make sure they're testing the right thing.
To actually see this work, you need to get the patch from jsonapi extras so that you can configure it to globally allow include counts.
Comment #57
dpolant commentedWrong patch last time. Here is the correct one.
Comment #58
e0ipsoI made these changes on commit:
We want to set this to
FALSE.This needs to go.
Awesome job!