Closed reilnuud closed 1 month ago
Sorry, I didn't mean to hit submit here since this is a q and not an issue and just meant to ask in the discord, but thanks for the quick reply!
We are using a CMS that appends a url parameter to get draft content -- we were passing an argument to getClient to do this (bad, I know) but now that getClient throws an error when this is done, how do we modify the uri for a request ad-hoc?
So normally a url would look like:
Normal request: https://cms.sample.com/api
Preview data request: https://cms.sample.com/api?token=foo
What we were doing:
public, cached data
const { data } = await getClient().query({ query, variables });
private, uncached draft data
const { data } = await getClient(token).query({ query, variables });
export const { getClient } = registerApolloClient(token => {
// add the token to the uri in case we're getting preview data
const uri = token
? `${process.env.CMS_API_URL}?token=${token}`
: process.env.CMS_API_URL;
return new ApolloClient({
cache: new InMemoryCache({
possibleTypes,
}),
link: new HttpLink({
uri,
headers: {
Authorization: `Bearer ${process.env.CMS_AUTH_TOKEN}`,
},
}),
});
});
export default getClient;
It's probably better in an issue, since you'll not be the last person with this question :)
So I'll write a bit more of a "general answer here":
Generally, there are a few different ways you can modify the uri
of outgoing requests.
You can just use the uri
value in context
with an outgoing query
const { data } = await getClient().query(MY_QUERY, {
context: {
uri: "someOtherUri",
},
fetchPolicy: "no-cache",
});
In an uri
callback you have access to the full operation
, which means that you could look at things like operation.operationName
or operation.variables
- or in this example, operation.getContext()
.
export const { getClient } = registerApolloClient(() => {
return new ApolloClient({
cache: new InMemoryCache({
// ...
}),
link: new HttpLink({
uri(operation) {
const context = operation.getContext();
if (context.token) {
return `${process.env.CMS_API_URL}?token=${context.token}`;
}
return process.env.CMS_API_URL;
},
// ...
}),
});
});
In your case, you'd then call that with token
in the context
- your call site wouldn't really be aware of the uri
abstraction:
const { data } = await getClient().query(MY_QUERY, {
context: {
token: "myToken",
},
fetchPolicy: "no-cache",
});
fetchPolicy: "no-cache"
.That's not generally necessary, but something to consider: You are redirecting your Apollo Client to a different data source here. If you wouldn't use no-cache
, the results from that other data source would get merged into your existing InMemoryCache - and in your case, where you probably have "original" and "draft" with the same typename and id
, there's a risk that the drafts would overwrite the originals in the cache.
With that warning note from the last example - you might also want to consider creating more than one cache.
In that case, call registerApolloClient
twice to intentionally create up to two independent cache instances per incoming request (they will be created once you call getClient
respectively).
const { getClient } = registerApolloClient(...)
// this will probably still need something like context to pass in the token for this cache on this request., unless you get the token from a cookie, then you can directly call `cookies()` inside the callback function in `registerApolloClient`.
const drafts = registerApolloClient(...)
later distinguish between getClient()
calls and drafts.getClient()
calls.
Awesome -- thanks! This is super helpful.
Great! I'm gonna close this issue then. Have a great day!
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.
Can you maybe provide a bit of code showcasing how you did it until now and where you were getting that url from in the first place?
Also, what was your expectation it would do? Return the same Apollo Client and just change the url? Return a new Apollo Client each call? Return a limited number of distinct Apollo Client instances?