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

[REQ] [Javascript] Repeat or copy api request #2890

Open
ybelenko opened this issue May 14, 2019 · 7 comments
Open

[REQ] [Javascript] Repeat or copy api request #2890

ybelenko opened this issue May 14, 2019 · 7 comments

Comments

@ybelenko
Copy link
Contributor

Is your feature request related to a problem? Please describe.

Current Javascript generator based on Superagent npm package to make Api calls. It provides option to retry http request when server doesn't respond. Ref to guide https://visionmedia.github.io/superagent/#retrying-requests

But real nightmare starts when you need to refresh access token every 15 minutes. Let's say server responds with 401 status when your access token expired.

import { UsersApi } from './api-sdk/src';

const api = new UsersApi();
api.getCurrentUser()
  .then((data) => {
    // succes, everything great
  })
  .catch((error) => {
    if (error.status === 401) {
      // obtain new success token and try again
      api.refreshToken(accessToken, refreshToken, scope)
        .then((data) => {
          // now we have valid access token and need to repeat request
          api.getCurrentUser()
            .then((data) => {
              // finally user data retrieved
            })
            .catch((error) => {
              // something completely wrong
            })
        })
        .catch((error) => {
          // maybe api server is down
        })
    }
  });

Describe the solution you'd like

I think that error instance in reject callback should contain request instance or method to call the same endpoint again.
Maybe

api.getUser()
  .then((data) => {

  })
  .catch((error) => {
    const { apiRequest } = error;
    apiRequest.reset();
    apiRequest.call();
  });

Describe alternatives you've considered

or another example, but I don't know how to write it clean with promises:

const originalRequest = api.getUser();
originalRequest.call();

// when you need to repeat the same call
const clonedRequest = api.clone(originalRequest);
clonedRequest.call();

In a perfect world this issue requires some kind of middleware, I think. Middleware intercepts every failed request ended with 401 response, refreshes token and makes the same call again. Developer can write that middleware when he got option to recreate original request within error callback.

cc @jfiala @achew22 @jaypea

@wing328
Copy link
Member

wing328 commented May 17, 2019

What about enhancing the API client to automatically refresh the expired token instead?

@ybelenko
Copy link
Contributor Author

@wing328
Good point.

I thought about that, but the problem is OAuth2 wasn't a standard for a long time(I'm not sure, but I read about that in many guidence and tutorials) and now it's in PROPOSED STANDARD status. There are a lot of custom implementations of OAuth2 in the web. I think it will be very difficult to add automatic refresh token feature and meet all developers requirements. There should be options to override almost every step and part(refresh token request path, Content-Type, response scheme etc.) of the process.

If Javascript template creators are agree to add such an option(even without override options, I can change js mustache templates anyway) I'm all hands up. Right now client SDK doesn't have method to obtain token and we discuss refresh token method already. 😄

OAuth 2.0 - 6. Refreshing an Access Token

@ybelenko
Copy link
Contributor Author

ybelenko commented Jun 9, 2019

Hmmm... even Superagent maintainer thinks that request clone feature is useless 😄
Ref to rejected PR: ladjs/superagent#627

However there are no superagent plugins to recreate request, at least I didn't found one. Existing plugins list from official Superagent readme doesn't contain anything like that.

I would like to make a PR, but I don't even know where to start... should I work on superagent itself, or better to create superagent plugin, or enhance javascript generator template.

Hope that somebody from js template creators will join conversation.

cc @jfiala @achew22 @jaypea

@ybelenko
Copy link
Contributor Author

ybelenko commented Jun 11, 2019

Possible workaround with current Javascript es6 promise SDK:

import { UsersApi } from '../../../api-sdk/src';

const sendApiRequest = (ApiClass, apiMethod, onSuccess, onError, ...params) => {
  const api = new ApiClass();
  api[apiMethod].apply(api, params)
    .then(onSuccess)
    .catch(err => {
      if (err.status === 401) {
        // refresh token and try again
        api.refreshAccessToken()
          .then(data => {
            // got refreshed token, try again
            const newApiInstance = new ApiClass();
            newApiInstance[apiMethod].apply(api, params)
              .then(onSuccess)
              .catch(onError);
          })
          .catch(err2 => {
            if (err2.status === 401) {
              // second fail, sign out
              return;
            }
            onError(err2);
          });
        return;
      }

      onError(err);
    });
};

// api call itself
sendApiRequest(
  UsersApi,
  'getUser',
  (data) => {
    // ok
  },
  (error) => {
    // logging error
  },
  1, // user id param
);

Looks awful, doesn't it?

@ybelenko
Copy link
Contributor Author

Finally Redux Toolkit contains builtin function to solve that issue:
Redux Toolkit - Automatic re-authorization by extending fetchBaseQuery

@cjurjiu
Copy link

cjurjiu commented Aug 9, 2021

Bump, any update on this? Having the same issue.

@ybelenko
Copy link
Contributor Author

ybelenko commented Aug 9, 2021

Bump, any update on this? Having the same issue.

I stopped using JavaScript sdk in favour of Redux Toolkit Query. Since my front contains about 10 simple queries I wrote them with JS fetch very fast.

If you're app contains Redux storage and your api requests are mainly typical then you should try it. RTK query also contains small generation tool which I didn't check. It should generate api slices from Openapi spec.

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

No branches or pull requests

3 participants