Authorization
Learn how to use convenience authorization helpers callApi provides
CallApi provides convenient authorization helpers via the auth property, making it easy to add authentication headers to your requests without manually constructing Authorization headers.
Bearer
Since Bearer is the most common authorization type, passing a string to auth automatically generates a Bearer Authorization header. You can also use an object with a bearer property.
import { createFetchClient } from "@zayne-labs/callapi";
// Passing a string
const callBackendApi = createFetchClient({
baseURL: "http://localhost:3000",
auth: "my-token",
});
// Passing an object
const result = await callBackendApi("/users/123", {
auth: {
type: "Bearer",
value: "my-token",
},
});The above is equivalent to writing the following with Fetch:
fetch("http://localhost:3000/users/123", {
headers: {
Authorization: `Bearer my-token`,
},
});You can also pass a function that returns a string or a promise that resolves to a string. This is useful for retrieving tokens dynamically:
import { createFetchClient } from "@zayne-labs/callapi";
const callBackendApi = createFetchClient({
baseURL: "http://localhost:3000",
});
const result = callBackendApi("/users/123", {
auth: {
type: "Bearer",
value: () => authStore.getToken(),
},
});The function will be called only once when the request is made. If it returns undefined or null, the header will not be added to the request. This allows for conditional authentication.
Token
Similar to Bearer authorization, but uses Token as the header prefix instead of Bearer.
import { createFetchClient } from "@zayne-labs/callapi";
const callBackendApi = createFetchClient({
baseURL: "http://localhost:3000",
auth: {
type: "Token",
value: "my-token",
},
});
const result = await callBackendApi("/users/123");The above is equivalent to writing the following with Fetch:
fetch("http://localhost:3000/users/123", {
headers: {
Authorization: `Token my-token`,
},
});Basic
Basic authentication adds username and password to the Authorization header, automatically base64 encoded.
import { createFetchClient } from "@zayne-labs/callapi";
const callBackendApi = createFetchClient({
baseURL: "http://localhost:3000",
auth: {
type: "Basic",
username: "my-username",
password: "my-password",
},
});You can also pass async getter functions for the username and password fields.
const { data } = await callApi("/api/data", {
auth: {
type: "Basic",
username: async () => await getUsername(),
password: async () => await getPassword(),
},
});Custom
For custom authorization schemes not supported by default, use the Custom type with prefix and value properties.
import { createFetchClient } from "@zayne-labs/callapi";
const callBackendApi = createFetchClient({
baseURL: "http://localhost:3000",
auth: {
type: "Custom",
prefix: "SomePrefix",
value: "my-token",
},
});
const result = await callBackendApi("/users/123");The above is equivalent to writing the following with Fetch:
fetch("http://localhost:3000/users/123", {
headers: { Authorization: `SomePrefix my-token` },
});Advanced Examples
Refreshing Tokens
A common use case for auth is combining it with error hooks to implement automatic session recovery or token refreshing.
Since the auth function is called right before every request, and manual refetch() preservation is built-in, you can handle 401 Unauthorized errors seamlessly:
import { createFetchClient } from "@zayne-labs/callapi";
const api = createFetchClient({
baseURL: "https://api.example.com",
auth: () => getAccessToken(),
onResponseError: async ({ response, options }) => {
if (response.status === 401) {
const newToken = await refreshToken();
localStorage.setItem("token", newToken);
options.refetch();
}
},
});Conditional Auth
Conditionally trigger authentication by returning null or undefined from your auth function when the user is not authenticated:
const client = createFetchClient({
baseURL: "https://api.example.com",
auth: async () => {
// Only add auth if user is logged in
const isLoggedIn = await checkAuthStatus();
// Returning null means no auth header will be added
return isLoggedIn ? await getToken() : null;
},
});
// Or dynamically per-request
async function makeRequest(endpoint: string, requiresAuth: boolean) {
return callApi(endpoint, {
auth: requiresAuth ? () => getToken() : undefined,
});
}Global Auth with Override
Define a global authentication strategy when creating a client and override or disable it for specific requests:
const client = createFetchClient({
baseURL: "https://api.example.com",
auth: () => getSessionToken(),
});
// Uses the global auth token
const userData = await client("/api/user");
// Override with a different token for a specific request
const adminData = await client("/api/admin", {
auth: () => getAdminToken(),
});
// Disable auth entirely for a specific request
const publicData = await client("/api/public", {
auth: undefined,
});Last updated on