API requests
Learn how to make requests to your Remix API in Makerkit
To make requests to the API functions in the api
folder, we provide a custom hook useApiRequest
, a wrapper around fetch
.
It has the following functionality:
- Uses an internal
state
to keep track of the state of the request, likeloading
,error
andsuccess
. This helps you write fetch requests the "hooks way" - Automatically adds a
Firebase AppCheck Token
to the request headers if you enabled Firebase AppCheck - Automatically adds a
CSRF token
to the request headers
Similarly to making Firestore Requests, it's a convention to create a custom hook for each request for readability/reusability reasons.
src/core/hooks/use-create-session.ts
import useApiRequest from '~/core/hooks/use-api';interface Body { idToken: string;}export function useCreateSession() { return useApiRequest<void, Body>('/api/session/sign-in');}
The hook returns an array with:
- the callback to make the request
- the state object of the request
const [createSession, createSessionState] = useCreateSession();
The state object internally uses useApiRequest
, and has the following interface:
{ success: boolean; loading: boolean; error: string; data: T | undefined;}
When success
is true
, the property data
is inferred with its correct type.
You can use this hook in your components:
import { useCreateSession } from '~/core/hooks/use-create-session';function Component() { const [createSession, createSessionState] = useCreateSession(); return ( <> { createSessionState.loading ? `Loading...` : null } { createSessionState.error ? `Error :(` : null } { createSessionState.success ? `Yay, success!` : null } <SignInForm onSignIn={(idToken) => createSession({ idToken })} /> </> );}
Similarly, you can also use it to fetch data:
import { useCreateSession } from '~/core/hooks/use-create-session';function Component() { const [fetchMembers, { loading, error, data }] = useFetchMembers(); // fetch data when the component mounts useEffect(() => { fetchMembers(); }, [fetchMembers]); if (loading) { return <div>Fetching members...</div>; } if (error) { return <div>{error}</div>; } return ( <div> {data.map(member => <MemberItem member={member} />)} </div> );}