next-drupal icon indicating copy to clipboard operation
next-drupal copied to clipboard

Help with next_jsonapi.size_max

Open zanami opened this issue 2 years ago • 8 comments

https://next-drupal.org/guides/page-limit

To override the page max size, set the following parameter in your Drupal settings.yml file and clear caches.

parameters:
  next_jsonapi.size_max: 100 // Set your max limit here.

Where exactly do I put this? What is 'Drupal settings.yml'?

zanami avatar Feb 10 '23 08:02 zanami

I guess there should be "services.yml" instead of "settings.yml"

theRuslan avatar Feb 10 '23 12:02 theRuslan

Yes. Thank you @theRuslan

shadcn avatar Feb 10 '23 16:02 shadcn

Thanks!

One more thing — looks like next_jsonapi prevents jsonapi_extras from overriding page[limit]. Here's a link, I can confirm.

zanami avatar Feb 13 '23 00:02 zanami

I tried with this

parameters:
  next_jsonapi.size_max: 100 // Set your max limit here.

in services.yml still, I am able to see only 50

Mukeysh avatar Mar 20 '23 09:03 Mukeysh

I have the same problem, it seems like those settings have no impact at all. I also tried to accomplish the same thing with a contrib module: https://www.drupal.org/project/jsonapi_page_limit --> But this also has no impact.

I was digging a little bit by try to see if the code inside of the php-drupal services of those modules gets executed at any time, but it is absolutely not called (both modules), not on request and also not on drush.

somebody any hints / ideas about that?

in the measwhile i have used a workaround by using multple roundtrips with this function:

import { getDrupalClient } from '.../utils';
import { JsonApiWithAuthOptions, JsonApiWithLocaleOptions } from 'next-drupal';

export const getRessourceCollectionLimitless = async (
  type: string,
  options:
    | ({ deserialize?: boolean | undefined } & JsonApiWithLocaleOptions &
        JsonApiWithAuthOptions)
    | undefined,
  limit: number | undefined = undefined,
  preData: any[] | undefined = undefined
) => {
  const drupalClient = getDrupalClient();
  const collection: any = await drupalClient.getResourceCollection(type, {
    ...options,
    deserialize: false
  });

  const deserializedCollection = drupalClient.deserialize(collection) as any[];

  let dataRessourceCollection: any[] = [
    ...deserializedCollection,
    ...(preData ?? [])
  ];

  if (
    collection &&
    'links' in collection &&
    typeof collection.links?.next !== 'undefined' &&
    (typeof limit === 'undefined' ||
      (limit && limit > dataRessourceCollection.length))
  ) {
    dataRessourceCollection = await getRessourceCollectionLimitless(
      type,
      {
        ...options,
        params: {
          ...options?.params,
          'page[offset]': collection.data.length
        }
      },
      limit,
      dataRessourceCollection
    );
  }

  return dataRessourceCollection.slice(0, limit);
};

Maybe someone finds this helpful...

devtim123 avatar May 03 '23 10:05 devtim123

@devtim123 Are you passing path as the first field for the entity type? We use path as a control for the page size.

See examples on https://next-drupal.org/guides/page-limit

shadcn avatar May 03 '23 13:05 shadcn

when i implement this as in your example of docs i facing following issues:

  • typescript is not happy, as option parameter of getResourceCollection actually does not provider a Record<string, string> value.
  • the results are still limited to 50
  • checking what path is requested via debug mode tells me, that those option does not effect anyting.

i was trying to give it a try with the params option, but also with no succuess...

what should be the corrent api call to drupal, something like this? http://drupal.docker.localhost/jsonapi/node/article?fields[node--article]=title,path&page[limit]=60 --> was also not working

after changing this to http://drupal.docker.localhost/jsonapi/node/article?fields[node--article]=path,title&page[limit]=60 it works now, yeah! (the order of fields[node--article] to be set to path,title and not title,path was important)

when we adopt this to next-drupal SDK is should be altered on two placed:

  1. change fieldto fields
  2. add options into params

A working example look then like this:

    const articles = await drupalClient.getResourceCollection(
      'node--article',
      {
        params: {
          'fields[node--article]': 'path,title',
          'page[limit]': 600
        }
      }
    );

why the path field is required to override the hard limit of 50?

thanks @shadcn for pushing me into right direction!

devtim123 avatar May 03 '23 22:05 devtim123

why the path field is required to override the hard limit of 50?

We use path as a control for overriding the size_max. The reason we do this is JSON:API favors pagination over fetching large amount of resources from Drupal.

However, in certain situation (see fetching paths in getStaticPaths), you do want to fetch more than the limit. We use path to do that.

The reason we do that and that the order matters is we want to enforce sparse fieldset. The consumer of the API has to intentionally pass a subset of the fields to fetch. This prevents over-fetching.

shadcn avatar May 04 '23 07:05 shadcn