Creating an auth hook with Apollo
I am a huge fan of Apollo. I find their internal caching mechanisms to be a really great tool. One thing I found myself doing a lot was using my GetUser
query in several components. In order to refactor this I went ahead and made a pretty standard hook useAuth
. This hook will return either a user, if logged in, or undefined if not. Additionally, it also passes in the logoutUser
function. The code looks like the following:
export function useAuth(fetchPolicy?: WatchQueryFetchPolicy) {
const { data, error } = useQuery<GetUser>(GET_USER, {
fetchPolicy: fetchPolicy ?? 'cache-first',
})
const [logoutUser, { client }] = useMutation<Logout>(LOGOUT_USER, {
onCompleted: () => {
client.clearStore()
},
})
return {
user: error !== undefined ? undefined : data?.me,
logoutUser,
}
}
Now, if a developer wants to access the currently authed user in any component, they can simply use the hook like so:
const { user } = useAuth()
One additional convenience parameters I added was the fetchPolicy
. This enables the developer to determine the level of caching the query uses. You can read about the supported Apollo fetch policies here. By default, we use cache-first
. The means, that Apollo is simply checking the cache for the user and if all the data is available, it won't make a network call to the backend.
If you knew for some reason that you would in fact like to bypass the local cache, you can pass in something like:
const { user } = useAuth('network-only')
This will now execute the GetUser
query against the GraphQL service and store the new values in the cache.
Lastly, one convenient part of having other auth-related functionallity in this hook is the developer doesn't need to remember all the requirements when performing a certain action. For instance, on the logoutUser
function, you can see we clear the client store (i.e. nuke the cache). If I were to manually have that logout code in all the components that could possibly log the user out, I may forget to do this which would result in undesired behavior.
In sum, this is a pretty straightforward refactor but figured I'd share these convenient hooks that I have found helpful during development.