Fetcher

Fetch data from the server.

Usage

Server-side only

The fetcher() function is only server-side. You cannot use it on the client-side.

Initial client

fetcher() is a function to create client. Pass generic type with the response type and pass the plugin and module as arguments.

As an example, we will pass UsersTypes as a generic type.

import { fetcher } from 'vitnode/lib/fetcher';
import { UsersTypes } from 'vitnode/api/modules/users/users.module';
const client = await fetcher<UsersTypes>({
  plugin: 'core',
  module: 'users',
});

Options

You can pass the options object to modify the fetch function. For example we can pass cache option to enable the cache.

const client = await fetcher<UsersTypes>({
  plugin: 'core',
  module: 'users',
  options: {
    cache: 'force-cache',
  },
});

Fetch data

Call client.{path}.{method} with the data you want to send to the server as an argument.

const data = await client.sign_in.$post(input);

Server Functions

Methods like POST, PUT and DELETE require to use Server Functions. You can create mutation-api.ts file and use it to call the fetcher() function with FetcherInput type.

mutation-api.ts
'use server';
 
import { UsersTypes } from 'vitnode/api/modules/users/users.module';
import { fetcher, FetcherInput } from 'vitnode/lib/fetcher';
 
export const mutationApi = async (
  input: FetcherInput<UsersTypes, '/sign_in', 'post'>,
) => {
  const res = await fetcher<UsersTypes>({
    plugin: 'core',
    module: 'users',
  });
 
  await res.sign_in.$post(input);
};

Now you can call the mutationApi() function on the server-side.

useForm.ts
export const useForm = () => {
  const onSubmit = async (values: z.infer<typeof formSchema>) => {
    await mutationApi({
      json: values,
    });
  };
 
  return {
    onSubmit,
  };
};

Handling errors

You can handle errors by checking the status property of the response.

mutation-api.ts
export const mutationApi = async (
  input: FetcherInput<UsersTypes, '/sign_in', 'post'>,
) => {
  const res = await fetcher<UsersTypes>({
    plugin: 'core',
    module: 'users',
  });
 
  await res.sign_in.$post(input);
  const data = await res.sign_in.$post(input);
 
  if (data.status !== 200) {
    return { message: await data.text() };
  }
};
useForm.ts
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';
 
export const useForm = () => {
  const t = useTranslations('core.global.errors');
 
  const onSubmit = async (values: z.infer<typeof formSchema>) => {
    const mutation = await mutationApi({
      json: values,
    });
 
    if (!mutation?.message) return;
 
    toast.error(t('title'), {
      description: t('internal_server_error'),
    });
  };
 
  return {
    onSubmit,
  };
};

Handling set-cookies

React Server Components cannot handle set-cookies headers. You need to handle them by using the handleCookiesFetcher() function.

mutation-api.ts
'use server';
 
import { UsersTypes } from 'vitnode/api/modules/users/users.module';
import {
  fetcher,
  FetcherInput,
  handleSetCookiesFetcher,
} from 'vitnode/lib/fetcher';
 
export const mutationApi = async (
  input: FetcherInput<UsersTypes, '/sign_in', 'post'>,
) => {
  const res = await fetcher<UsersTypes>({
    plugin: 'core',
    module: 'users',
  });
 
  await res.sign_in.$post(input);
  const data = await res.sign_in.$post(input);
  await handleSetCookiesFetcher(data);
};

Client-side

If you want to use the fetcher() on the client-side, you need to use the fetcherClient() function.

 

Custom fetcher

If you want you can create your own fetch function, but you need to remember to pass headers like:

  • x-forwarded-for header - client IP address,
  • Cookie header - client cookies,
  • user-agent header - client user agent.

On this page