question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: Async Client fetchOptions support

See original GitHub issue

Summary

We use Keycloak as a service-to-service authentication layer, and want to use URQL on server. Grabbing a (JWT) access token means reaching out to it over the network, and tokens have a low TTL with a refresh token. The way we could resolve this with current implementation is “hacky”, in pseudo-code:

let token;

const client = createClient({
  url: 'http://bla.bla',
  fetchOptions: () => ({
    headers: {
      Authorization: `Bearer ${token}`
    }
  }),
});

// here's where it gets awks

getToken().then(t => {
  const jwt = decode(t)
  token = jwt.access_token
  setTimeout(() => {
	t = null;
    getToken();
  }, jwt.expiration_date).unref() // just to sketch, it's not how it works obvsly.
});

This kind of works (I know it can be made to work correctly), but there’s a real chance that if this server is under high load that some requests miss their token while a new one is being requested. Making this code work just gets more and more awkward…

Proposed Solution

I understand this has potential performance implications, but what if fetchOptions’s function form has this signature instead of the existing one?

fetchOptions: RequestInit | () => RequestInit | () => Promise<RequestInit>

This would quite elegantly solve our problem:

const client = createClient({
  url: 'http://bla.bla',
  fetchOptions: async () => ({
    headers: {
      Authorization: `Bearer ${await getOrFetchToken()}`
    }
  })
})

Requirements

  • Should not break existing behavior
  • Existing behavior should take as little of a performance hit as possible.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:10
  • Comments:13 (13 by maintainers)

github_iconTop GitHub Comments

2reactions
kittencommented, Sep 10, 2020

Closed since #939 is merged. Let’s see how that goes for now! 🙌

1reaction
JoviDeCroockcommented, May 6, 2020

Hey,

I like the idea since it solves cases for react-native,… as well, if only the fetchExchange has to worry about this we should be fine.

Just a sidenote: at this moment in time we advise this to be solved in an exchange https://formidable.com/open-source/urql/docs/common-questions/#how-do-we-achieve-asynchronous-fetchoptions

Read more comments on GitHub >

github_iconTop Results From Across the Web

RFC: Async Client fetchOptions support · Issue #794 · urql- ...
Summary We use Keycloak as a service-to-service authentication layer, and want to use URQL on server. Grabbing a (JWT) access token means ...
Read more >
RFC 7240: Prefer Header for HTTP
The selection of which type of response to return to the client generally has no ... Therefore, whether and how any given server...
Read more >
Data Fetching
We recommend reading the support for promises React RFC which introduces async / await in Server Components and a new use() hook for...
Read more >
Determining Resources for Asynchronous and ...
There are two stages in calculating the resources for an application server. First, the system checks whether there are enough local resources for...
Read more >
Fetch Standard
Credentials are HTTP cookies, TLS client certificates, ... This determines which service workers will receive a fetch event for this fetch.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found