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

Possibility to pass context/options from query-executor to the client/request #1538

Open
mirismaili opened this issue May 16, 2023 · 3 comments · May be fixed by #1777
Open

Possibility to pass context/options from query-executor to the client/request #1538

mirismaili opened this issue May 16, 2023 · 3 comments · May be fixed by #1777

Comments

@mirismaili
Copy link

mirismaili commented May 16, 2023

We have some special APIs with multiple token types. In GraphQL ones, we use Apollo Client and it has this feature:

new ApolloClient({
  link: setContext(async (operation, context) => ({
      headers: {
        Authorization: await getTokenUtil(context.tokenType), // <--- See here
        ...context.headers,
      },
    })),
  // ...
})

And the user can send the context per query/mutation:

apolloClient.query({
  query: gql`...`,
  context: { tokenType: X },  // <--- See here
})

But in REST ones that we use OpenAPI and this useful tool (openapi-typescript-codegen), we can't send any data from query-executor to the client or request:

openapi --input ./spec.json --output ./generated --name AppClient
const appClient = new AppClient({
    // The `options` pararmeter here, is hard-coded in the generated codes
    // (including `{method, url, query, errors}`):
    TOKEN: async (options: ApiRequestOptions) => await getTokenUtil(/* ??? */),
});

// THIS METHOD DOESN'T ACCEPT ANY EXTRA DATA (except query parameters):
const response = await appClient.organizations.createOrganization({
  name: 'OrgName',
  description: 'OrgDescription',
})
@donkee
Copy link

donkee commented Jul 13, 2023

I would also like this feature. We have a few endpoints for downloading files and require the requestType: arrayBuffer axios config option for them to work for us. For now we are just calling axios directly for those endpoints

@eakorolev eakorolev linked a pull request Sep 21, 2023 that will close this issue
@mirismaili
Copy link
Author

mirismaili commented Oct 29, 2023

PR #1777 is a good feature. But it doesn't resolve this issue necessarily. Because I want to write a single HEADERS method that has access to request context/options (so can return different values for different requests). With #1777 I need to rewrite HEADERS for each request.

@eakorolev
Copy link

@mirismaili I'm with you, and I tried to find some solution. Follow my thougths:

  1. I'd love to have a single instance of service, and only a single HEADERS method instantiated.
  2. This the only HEADERS method should have an access to current req object. But it only can reach self-scoped variables or some variables from its closure.
  3. So we have to create a long-living variable (let's name it CURRENT_REQ) at same level where HEADERS method is declared. And we have to update the CURRENT_REQ value for every request we serve.
  4. The generated code is async, and it should serve a few request at the single moment. Best I can do is to rewrite CURRENT_REQ = req right before I make a call service.makeAnAPICall(someParams). But the _request method is async too, that means that some other incoming request can re-write the CURRENT_REQ value while _request is awaiting for some value.

That is why you can't use a closured variable to store current request object. Thus you can't have a single long-living instance of HEADERS. And that's why I decided to instantiate the HEADERS method for every API call.

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

Successfully merging a pull request may close this issue.

3 participants