Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On a successful await client.groupApi.listGroupUsers request, the headers contains no useful information. #403

Open
JekaPolihovic opened this issue Sep 7, 2023 · 15 comments
Labels

Comments

@JekaPolihovic
Copy link

JekaPolihovic commented Sep 7, 2023

Describe the bug

Upon successful request await client.groupApi.listGroupUsers and others to Okta Api using okta-sdk-nodejs, does not contain such information as X-Rate-Limit-Limit, X-Rate-Limit-Remaining, X-Rate- Limit Reset.

I'm making a request. Successfully receive response: 200 OK

const collectionGroupUsers = await client.groupApi.listGroupUsers({ groupId: group.id });

await collectionGroupUsers.each((user) => {
    users.push(user?.profile?.login || user.id);
});

I want to read headers and find there information about X-Rate-Limit-Limit, X-Rate-Limit-Remaining, X-Rate-Limit-Reset. But on a successful request, headers does not contain such information. Only when an error is received, such information is in the request headers.

If I do console.log(collectionGroupUsers);
He will show me:

collectionGroups: Collection {
   nextUri: 'https://example.okta.com/api/v1/groups?expand=stats',
   httpApi: Http {
     defaultHeaders: {
       'User-Agent': '@okta/okta-sdk-nodejs/7.0.1 node/16.9.1 darwin/21.6.0'
     },
     requestExecutor: DefaultRequestExecutor {
       _events: [Object: null prototype] {},
       _eventsCount: 0
       _maxListeners: undefined,
       requestTimeout: 0
       maxRetries: 0
       retryCountHeader: 'X-Okta-Retry-Count',
       retryForHeader: 'X-Okta-Retry-For',
       [Symbol(kCapture)]: false
     },
     cacheStore: MemoryStore { _keyLimit: 100000, _store: Map(0) {} },
     cacheMiddleware: [Function: defaultCacheMiddleware],
     defaultCacheMiddlewareResponseBufferSize: undefined,
     oauth: OAuth { client: [Client], accessToken: null }
   },
   factory: { parseResponse: [Function: parseResponse] },
   currentItems:[],
   request: RequestContext {
     httpMethod: 'GET',
     headers: { Accept: 'application/json, */*;q=0.8' },
     body: undefined
     affectedResources: [],
     isCollection: false
     startTime: undefined
     agent: undefined
     url: {
       slashes: true
       protocol: 'https:'
       hash: '',
       query: [object],
       pathname: '/api/v1/groups',
       auth: '',
       host: 'example.okta.com',
       port: '',
       hostname: 'example.okta.com',
       password: '',
       username: '',
       origin: 'https://example.okta.com',
       href: 'https://example.okta.com/api/v1/groups?expand=stats'
     }
   }
};

How to get information about X-Rate-Limit-Limit, X-Rate-Limit-Remaining, X-Rate-Limit-Reset from a successful request?

Reproduction Steps?

I run this code:

const collectionGroupUsers = await client.groupApi.listGroupUsers({ groupId: group.id });

await collectionGroupUsers.each((user) => {
    users.push(user?.profile?.login || user.id);
});

SDK Versions

'@okta/okta-sdk-nodejs/7.0.1 node/16.9.1 darwin/21.6.0'

Additional Information

No response

@jaredperreault-okta
Copy link
Contributor

jaredperreault-okta commented Sep 8, 2023

Thanks for the report, we'll look into this!

Internal Ref: OKTA 645744

@JekaPolihovic
Copy link
Author

@jaredperreault-okta Thanks for answering.
Dont have access to Internal Ref: OKTA-645744

@jaredperreault-okta
Copy link
Contributor

@JekaPolihovic Yes, you're not supposed to 😅

I'll update this thread once progress has been made

@JekaPolihovic
Copy link
Author

@jaredperreault-okta Thank you very much, I’ll wait, this change is important for us!

@jaredperreault-okta
Copy link
Contributor

@JekaPolihovic Do you mind elaborating on your use case a bit? A Collection is a wrapper around paginated results, so providing header details like collectionGroupUsers.headers might be a bit awkward, because the headers could change if multiple network requests are sent during iteration (via pagination).

Have you considered using a custom RequestExecutor? https://github.com/okta/okta-sdk-nodejs#request-executor

@JekaPolihovic
Copy link
Author

@jaredperreault-okta Yes, we use this RequestExecutor solution, but we still face the problem of exceeding the Api request limit.

For this reason, I studied this article: https://developer.okta.com/docs/reference/rl-best-practices/

And I want to get these headers from the response, how can I do this?

X-Rate-Limit-Limit - the rate limit ceiling that is applicable for the current request.
X-Rate-Limit-Remaining - the number of requests left for the current rate-limit window.
X-Rate-Limit-Reset - the time at which the rate limit resets, specified in UTC epoch time (in seconds).

@jaredperreault-okta
Copy link
Contributor

The fetch method of the RequestExecutor (or the .on('response') events) will give you access to fetch Response instances, which will have access to the headers.

Can you provide your RequestExecutor code snippet?

@JekaPolihovic
Copy link
Author

@jaredperreault-okta
Can you give an example using my code as an example?


import OktaSdk from '@okta/okta-sdk-nodejs';

const { Client, DefaultRequestExecutor } = OktaSdk;

const customDefaultRequestExecutor = new DefaultRequestExecutor({
      maxRetries: 0,
      requestTimeout: 0 // Specify in milliseconds if needed
    });

      this.oktaClient = new Client({
        ...this.connectionInfo,
        requestExecutor: customDefaultRequestExecutor
      });
   
const collectionGroupUsers = await this.oktaClient.groupApi.listGroupUsers({ groupId: group.id });

await collectionGroupUsers.each((user) => {
     users.push(user?.profile?.login || user.id);
});

How to use RequestExecutor and how to use .on('response')

@jaredperreault-okta
Copy link
Contributor

@JekaPolihovic You can either extend the DefaultRequestExecutor class (doc) and override the fetch method, or you can subscribe to customDefaultRequestExecutor.on('response', res => { ... } );.

However the Collection class is designed to handle rate limiting; is there a specific reason you have set maxRetries to 0 (essentially disabling the feature)?

@JekaPolihovic
Copy link
Author

@JekaPolihovic You can either extend the DefaultRequestExecutor class (doc) and override the fetch method, or you can subscribe to customDefaultRequestExecutor.on('response', res => { ... } );.

However the Collection class is designed to handle rate limiting; is there a specific reason you have set maxRetries to 0 (essentially disabling the feature)?

Yes, we set maxRetries to 0 because do not want to limit the number of retries.

@JekaPolihovic
Copy link
Author

@JekaPolihovic You can either extend the DefaultRequestExecutor class (doc) and override the fetch method, or you can subscribe to customDefaultRequestExecutor.on('response', res => { ... } );.

However the Collection class is designed to handle rate limiting; is there a specific reason you have set maxRetries to 0 (essentially disabling the feature)?

@jaredperreault-okta I'll test if this: customDefaultRequestExecutor.on('response', res => { ... } ); returns the necessary headings and gets back to you with the answer! Thank you

@JekaPolihovic
Copy link
Author

@jaredperreault-okta We want to ensure that error 429 does not occur even once, because if it does occur, this is already a problem for us. Even if it is processed by the library when it appears, there is already a fact that it has appeared and this time it will already be registered in the Okta admin console

@jaredperreault-okta
Copy link
Contributor

jaredperreault-okta commented Sep 25, 2023

@JekaPolihovic Were you able to solve this issue using the RequestExecutor?

@JekaPolihovic
Copy link
Author

@JekaPolihovic Were you able to solve this issue using the RequestExecutor?

I'm currently testing this!
I will write how to solve this and we will close this issue.

@jaredperreault-okta
Copy link
Contributor

@JekaPolihovic Just following up, were you able to solve this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants