πŸ“– Calling APIs from the Client

To call an API from the client, use the built-in apiRequest function located at:

src/functions/serverRequest.ts

This function handles communication with your backend, sending data and receiving results from the server.


▢️ Example: Calling the saveUser API from the Client

src/dashboard/page.tsx
import { apiRequest, apiRequestReponse } from 'src/_functions/serverRequest';
import { useEffect } from "react";

export default function App() {
  useEffect(() => {
    (async () => {
      const response = await apiRequest({ 
        name: "saveUser",
        data: {
          name: "mike",
          email: "mike@gmail.com",
          password: "mike_2003"
        }
      })) as apiRequestReponse
      
      if (response.status == 'error') {
        toast.error(response.message || 'Internal server error')
      } else if (response.status != 'success') {
        toast.error('Internal server error')
      }

      console.log(response.result); // e.g { name: 'John' }
    })();
  }, []);

  return <div>Hello World</div>;
}

If you use the default return shape, you can add apiRequestResponse after the API call, as shown in the example above. If you use a custom return shape, you will need to define this yourself. The default return shape is shown at the bottom of the page.

If you dont return anything you dont need to define a return shape and you can void the result

void apiRequest({ name: 'test' })

🧠 apiRequest Parameters

Parameter
Type
Required
Description

name

string

βœ…

The name of the API you want to call (e.g. "saveUser")

data

object

❌

Optional data to pass to the API


πŸ› οΈ Example: Creating the saveUser API

src/dashboard/_api/saveUser.ts
import { PrismaClient } from '@prisma/client';
import { authSetup, sessionLayout } from 'config';

interface Functions {
  prisma: PrismaClient;

  saveSession: (sessionId: string, data: any) => Promise<boolean>;
  getSession: (sessionId: string) => Promise<any | null>;
  deleteSession: (sessionId: string) => Promise<boolean>;

  tryCatch: <T, P>(func: (values: P) => Promise<T> | T, params?: P) => Promise<[any, T | null]>;

  [key: string]: any; // allows for other functions that are not defined as a type but do exist in the functions folder
};

interface ApiParams {
  data: Record<string, any>;
  functions: Functions;
  user: sessionLayout;
};


const auth: authSetup = {
  login: true, //* checks if the session data has an id. 
  additional: [
    // { key: 'groupId', mustBeFalsy: false }, //* checks if the groupId is truethy, so if groupId is an empty string or 0 it will not pass
    // { key: 'admin', value: true }, //* checks if admin = true
    // { key: 'email', type: 'string' }, //* checks if the email is a string
    // { key: 'updatedAt', nullish: false } //* checks if the updatedAt is not null or undefined 
    //* you can perform certain checks with more than 1 condition but in the end they all have there own use case.
  ]
}

const api = async ({ data, functions, user }: ApiParams) => {
  console.log(data)
  console.log(functions)
  console.log(user)
  console.log('you just called the randomApi.ts')
  return { status: 'success', result: { name: 'John' } }
}

export { auth, api }

🧩 How it Works

The api function receives an object with 3 useful arguments automatically:

  • πŸ“¦ data β€” Contains the values from the data key passed from the client.

  • 🧰 functions β€” All exported utilities from server/functions/ (e.g. prisma, saveSession).

  • πŸ‘€ user β€” Contains values from the session. Default session keys are configured in config.ts under userData.

In the api function happends all your logic (e.g. fetching data).


πŸ” Auth

The auth object in the api file will do certain checks to allow or reject the user from accessing the api call.

  • login β€” checks if the users session object has an id stored in it.

  • additional β€” an array that can hold objects where we check for specific values in the users session, the object needs an key and than you can chose between

  1. mustBeFalsy β€” boolean (if true than the passes key needs to be a false value such as false, 0, -0, 0n, "", null, undefined or NaN, if false then the key needs to be a true value such as true, 1, 'a' or any other value)

  2. value β€” any (the exact value the key needs to have. this is a strict comparison)

  3. type β€” string | number | boolean | Date (checksthe type of the key. this is a strict comparison)

  4. nullish β€”boolean (if true then the key needs to be null or undefined, if false then the key needs to be not null and not undefined)

{ key: 'groupId', mustBeFalsy: false } { key: 'admin', value: true }


πŸ“¬ Returning Data from the API

The return value can be any shape you like. However, we recommend returning:

Parameter
Type
Required
Description

status

string

βœ…

Either success or error

result

object

❌

If you want to return an result, this can either be any value

message

string

❌

To pass an message you can use in the notify

messageParams

string

❌

To pass values you want to use in the notify e.g userName

This structure makes it easy to handle results in your frontend logic.

Last updated