# Making API Requests in Remix Firebase

> Learn how to make requests to your Remix API in Makerkit

*Canonical: https://makerkit.dev/docs/remix-fire/data-fetching/making-api-requests*

---

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.

 ```tsx {% title="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

```tsx
const [createSession, createSessionState] = useCreateSession();
```

The state object internally uses `useApiRequest`, and has the following
interface:

```tsx
{
  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:

```tsx
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:

```tsx
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>
  );
}
```
