This kit is no longer maintained.

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:

  1. Uses an internal state to keep track of the state of the request, like loading, error and success. This helps you write fetch requests the "hooks way"
  2. Automatically adds a Firebase AppCheck Token to the request headers if you enabled Firebase AppCheck
  3. 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:

  1. the callback to make the request
  2. 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>
);
}