Problem/Motivation

I strongly believed this show be provided out of the box with JSONAPI not JSONAPI Extra.
Quoting myself from #2995537: This is how I'm using JSON API and JSON API Extras

We ended up using JSON API Extras to leverage the count variable in the response. The idea was to get the count on the first request and then send subsequent parallel requests to fetch all the remaining nodes.

The biggest problem I have with this is once you enable count qurey it adds count to all collection responses which means two same queries on same run. This should be configureable per request should be prvided out the box.

Proposed resolution

Add count param to the entity collection endpoint to return the count on damand.

Remaining tasks

Finalize if want to do it or not.
Create patch.
Document it.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

jibran created an issue. See original summary.

e0ipso’s picture

I think that it's interesting to be able to trigger counts per request.

I am confused by the strong feelings about where this feature should live (JSON API Extras). Having an extra module will have a negligible impact on performance, but it may be another concern.

jibran’s picture

Let's create pro and cons list for not having it in JSON API :D

e0ipso’s picture

I'm OK with that. Although I'm also interested in what is not working with the current solution.

wim leers’s picture

Category: Task » Feature request
wim leers’s picture

Title: Allow adding count param to entity collection endpoint to return count » Allow adding ?count URL query arg to return collection count
Version: 8.x-1.x-dev » 8.x-2.x-dev
Issue tags: +API-First Initiative

This is how I understand this issue. Hopefully everyone finds this title clearer?

wim leers’s picture

Issue tags: +Performance

Although I'm also interested in what is not working with the current solution.

@jibran already explained that in the IS:

The biggest problem I have with this is once you enable count qurey it adds count to all collection responses which means two same queries on same run.

IOW: a performance problem.

wim leers’s picture

I would personally be okay with this feature by the way; it'd just be another profile to document in #2955020: Spec Compliance: JSON API's profile/extention (Fancy Filters, Drupal sorting, Drupal pagination, relationship arity) needs to be explicitly communicated. It's very simple. Not obtrusive. And it'd help make jsonapi_extras even simpler (and remove the need for it in this particular use case).

e0ipso’s picture

Given the performance impact I prefer this to be a server setting.

wim leers’s picture

Hrm… but right now that server setting is making every collection response slow. I think that's @jibran's complaint?

e0ipso’s picture

We could make it be a per resource type setting in jsonapi extras. My point is not to allow an ill intentioned anonymous user to add extra load, for this feature.

wim leers’s picture

I understand that. But custom query strings always allow you to bypass Drupal's caches. This is a widely known weakness. So I'm not concerned about this TBH.

e0ipso’s picture

Well, it's not only that they bust cache, but that they now can trigger a (potentially heavy) database query for the count.

wim leers’s picture

Yes. But they already can easily trigger much more expensive database queries by hitting a complex Views page while breaking the cache using a random query string.

You're right that it's desirable to avoid that cost. But I think you're not realizing how much bigger costs already exist aplenty elsewhere! 😭

e0ipso’s picture

We should strive to not make it worse, right?

In a separate topic, we have the chance to 4XX unknown query string parameters used for cache busting. Somehow I thought that was the case. If not, we can make that happen.

wim leers’s picture

In a separate topic, we have the chance to 4XX unknown query string parameters used for cache busting.

What do you mean?

You'll always be able to bypass Page Cache. Technically, Dynamic Page Cache is already helping us with query string cache busting, since it explicitly varies by url.query_args:fields, url.query_args:filter, and so on. But you can still bypass even that by passing ?filter=RANDOM, because it's impossible for us to validate all possible values for those URL query args.

I'm going to let this issue rest; it's not important enough compared to other issues to be spending more time on this theoretical cache busting discussion.

e0ipso’s picture

I'm going to let this issue rest; it's not important enough compared to other issues to be spending more time on this theoretical cache busting discussion

I was trying to communicate that the concern is not (only) cache busting.

Well, it's not only that they bust cache, but that they now can trigger a (potentially heavy) database query for the count.

By making this setting server-side (per resource type, as opposed to globally like it is now in JSON API Extras) it would help mitigate this concern. This would be the decision of a site admin, not a (potentially) malicious user.

Maybe we can also consider white listing resource types that can use the ?count query string parameter.

jibran’s picture

Title: Allow adding ?count URL query arg to return collection count » Allow resource types to be include count

After #3037039: Create a public API for indicating resource types should not be exposed, I think we should change the approach here so re-titled the issue.

We can add an extra param $is_countable to \Drupal\jsonapi\ResourceType\ResourceType::__construct and user can set it via ResourceTypeBuildEvent, thoughts?

jibran’s picture

Title: Allow resource types to be include count » Allow resource types to include count