API Calls

We've integrated Axios to handle API calls. By default, it uses the current host URL, but you can customize this in the .env file to suit your requirements.

.env
...
NEXT_PUBLIC_API_HOST=
...

Axios has been configured in the folder src/utils/axios.ts

Auth api work scenario

We have our all API's in the src/app/api directory. In this directory, there is a folder named auth, which contains our authentication-related APIs. The AUTH_PROVIDER can be set to either mock or supabase. Both options utilize the same API endpoint, with the backend dynamically invoking the corresponding business logic based on the AUTH_PROVIDER configuration. The authProvider.ts file manages this distinction by dynamically loading and returning the appropriate authentication provider module.

src/utils/api/auth/authProvider.ts
// @project
import { AUTH_PROVIDER } from '@/config';

export interface AuthProvider {
  login: (formData: Record<string, any>) => Promise<Response>;
  getUser: () => Promise<Response>;
  forgotPassword?: (formData: Record<string, any>) => Promise<Response>;
  resetPassword?: (formData: Record<string, any>) => Promise<Response>;
  signOut?: () => Promise<Response>;
  signUp?: (formData: Record<string, any>) => Promise<Response>;
  verifyOtp?: (formData: Record<string, any>) => Promise<Response>;
  resend?: (formData: Record<string, any>) => Promise<Response>;
}

// Mapping of auth types to dynamic imports
const authProviderMapping: Record<string, () => Promise<AuthProvider>> = {
  mock: () => import('@/utils/api/auth/mock/auth').then((mod) => mod.default as unknown as AuthProvider),
  supabase: () => import('@/utils/api/auth/supabase/auth').then((mod) => mod.default as unknown as AuthProvider),
  aws: () => import('@/utils/api/auth/aws/auth').then((mod) => mod.default as unknown as AuthProvider)
};

// Dynamically loads and returns the auth provider based on AUTH_PROVIDER.
export async function authProvider() {
  return await authProviderMapping[AUTH_PROVIDER]();
}

The code below defines a POST API route handler that dynamically invokes the appropriate login function based on the currently configured authentication provider.

src/utils/api/auth/index.ts
// @project
import { authProvider } from './authProvider';
import { attempt } from '@/utils/attempt';

export async function login(formData: Record<string, any>) {
  const authHandler = await authProvider();

  if (!authHandler.login) {
    return { data: null, error: 'Login not supported by current provider' };
  }

  return attempt(authHandler.login(formData));
}

For authentication, we have two distinct business logic implementations based on the selected AUTH_PROVIDER:

  1. Mock: The mock authentication logic is defined in src/app/api/mock/auth/index.ts.

src/utils/api/auth/mock/auth/index.ts
export async function login(formData: LoginFormInput) {
  return new Promise((resolve, reject) => {
    try {
     ...  // logic of mock
    } catch {
      reject(new Error('Server error'));
    }
  });
}

...
  1. Supabase: The Supabase authentication logic is defined in src/app/api/supabase/auth/index.ts.

src/utils/api/auth/supabase/auth/index.ts
export async function login(formData: LoginFormInput) {
  return new Promise(async (resolve, reject) => {
    try {
     ... // login of Supabase
    } catch {
      reject(new Error('Server error'));
    }
  });
}

... 

Last updated