# Fetching data from Supabase

> Learn how fetch data from your Supabase database in Makerkit and Next.js

*Canonical: https://makerkit.dev/docs/next-supabase-lite/data-fetching/fetching-data-supabase*

---

When fetching data from the Supabase Postgres Database, we use the Supabase
JS client.

To make data-fetching from Supabase more reusable, our convention is to
create a custom React hook for each query we make.

For example, let's take a look at the hook to fetch an organization from
Supabase.

First, we want to write a query that receives two parameters:
1. a Supabase client interface
2. an organization ID

 ```tsx {% title="organizations/queries.ts" %}
export function getOrganizationById(
  client: Client,
  organizationId: number
) {
  return client
    .from('organizations')
    .select(`
      id,
      name,
      logoURL: logo_url
    `)
    .eq('id', organizationId)
    .throwOnError()
    .single();
}
```

It's important that we pass the client as a parameter so that we can use the
function in both the browser and the server.

Now, if we want to use a React Hook to fetch the organization from one of
our components, we can use the `useSWR` hook from `swr`:

```tsx
import useSupabase from '~/core/hooks/use-supabase';
import { getOrganizationById } from '~/lib/organizations/database/queries';
import useSWR from 'swr';

function useOrganizationQuery(
  organizationId: number
) {
  const client = useSupabase();
  const key = ['organization', organizationId];

  return useSWR(key, async () => {
    return getOrganizationById(client, organizationId).then(
      (result) => result.data
    );
  });
}

export default useOrganizationQuery;
```
---


There are two ways to use this function:

1. **Server**: directly, in a server-side function such as: a Route Handler, a Server Action, a Server Component, or a Middleware
2. **Client**: indirectly, in a React Hook in a client-side component

### Retrieving data in a server-side function

Let's see some scenarios where we can use this function in a server-side.

#### Route Handler

When you are fetching data from a Route Handler, you can use the `getSupabaseRouteHandlerClient` function.

 ```tsx {% title="pages/api/organizations/[id]/route.ts" %}

import { getOrganizationById } from '~/lib/organizations/database/queries';
import getSupabaseRouteHandlerClient from '~/core/supabase/route-handler-client';
import { NextRequest, NextResponse } from "next/server";

export const GET = async (
  req: NextRequest,
  { params }: { params: { id: string } }
) => {
  const client = getSupabaseRouteHandlerClient();
  const { data } = await getOrganizationById(client, params.id);

  return NextResponse.json(data);
};
```

### Server Action

When you are performing mutations using React Server Actions, you can use the `getSupabaseServerActionClient` function to read data from the Supabase database.

```tsx
'use server';

import getSupabaseServerActionClient from '~/core/supabase/action-client';
import { getOrganizationById } from '~/lib/organizations/database/queries';

export async function getOrganizationByIdAction(
  organizationId: number
) {
  const client = getSupabaseServerActionClient();
  const { data } = await getOrganizationById(client, organizationId);

  return data;
}
```

### Server Component

When you are fetching data from a Server Component, you can use the `getSupabaseServerComponentClient` function.

```tsx
import getSupabaseServerComponentClient from '~/core/supabase/server-component-client';
import { getOrganizationById } from '~/lib/organizations/database/queries';

interface Params {
  params: {
    id: string;
  };
}

async function OrganizationPage({ params }: Params) {
  const client = getSupabaseServerComponentClient();
  const organization = await getOrganizationById(client, params.id);

  return <div>{organization.name}</div>;
}
```

### Retrieving data using a React hook

Now that we have a hook to fetch an organization, we can use it in our
components to retrieve the data.

```tsx
import { useOrganizationQuery } from './use-organization-query';

function OrganizationCard({ organizationId }) {
  const {
    data: organization,
    isLoading,
    error
  } = useOrganizationQuery(organizationId);

  /* data is loading */
  if (isLoading) {
    return <div>Loading...</div>
  }

  /* request errored */
  if (error) {
    return <div>Error!</div>
  }

  /* request successful, we can access "organization" */
  return <div>{organization.name}</div>;
}
```
