This question is probably a sign of my misunderstanding of the philosophy of Apollo/React/GraphQL, but I'm a bit stuck here.
I am writing the authentication logic for my single page app. I have a backend with a GraphQL API that authenticates users by returning a JWT access/refresh token pair. So, to login, I need to send a mutation to the GraphQL endpoint from my app.
My frontend uses Apollo Client. Now I understand I can run a mutation with useMutation
, I understand how this works. But I also know that React Hooks need to be specified at the top of a component. I could have this useMutation
call in a login component, but this feels like bad encapsulation.
The problem is that I want to have a separate login
utility function that takes a username and password, sends the login mutation request to the backend, and returns the response.
From my understanding, I cannot use useMutation
here, as I'm not in a React component. I can of course write a fetch
call myself:
export const login = (username, password) => {
return fetch("/api", {
method: "POST",
...
}
but this feels unclean when I'm working within the Apollo Client ecosystem. Am I missing something, should I just roll ahead with these manual fetch calls, or am I misunderstanding the whole philosophy here?
As long as you have access to an instance of ApolloClient
, you can call the mutate method on it directly. You can also pass the client in as a parameter, in which case you might find it helpful get the client instance through the useApolloClient hook. Alternatively, you can just export the client and then import it directly inside your function. Whatever approach you take, just make sure you're using the same instance of ApolloClient
that you use elsewhere in your app to ensure you're updating the correct cache.
const client = new ApolloClient({...})
...
const { data, errors } = await client.mutate({...})