@niteen5/api-nexus
v0.0.2
Published
A sleek, typed API orchestration layer supporting native fetch (default) or axios.
Downloads
184
Maintainers
Readme
@niteen5/api-nexus
A sleek, fully-typed API orchestration layer for React, Next.js, and any JavaScript/TypeScript project. Supports native fetch (default, zero dependencies) or axios — your choice.
✨ Features
- 🔁 Adapter pattern — swap between
fetchandaxioswith one config line - 🔐 Built-in auth — pass a
getToken()function, Bearer headers are handled automatically - 🧩 Strongly typed endpoints — your endpoint map gives you full IntelliSense on every
call() - 📦 Zero mandatory dependencies — native
fetchis the default; axios is optional - 🛤️ Path params & query strings — built-in support for
{id}replacements and query serialization - 🧼 Consistent response shape — every call returns
{ isSuccess, data, error, status, message } - ⚡ CLI scaffold — run
npx api-nexusto generate boilerplate in seconds
📦 Installation
npm install @niteen5/api-nexus
# or
yarn add @niteen5/api-nexus
# or
pnpm add @niteen5/api-nexusIf you want to use axios as the HTTP client, install it too:
npm install axios
⚡ Quickest Start — CLI Scaffold
Run this in your project root right after install and you're done:
npx api-nexusThis generates a ready-to-use src/api/ folder for you:
src/
└── api/
├── endpoints.ts ← your endpoint map (edit this)
└── index.ts ← your configured api instance (ready to import)It will ask if you have axios installed and set up the right adapter automatically. That's it — skip the manual steps below if you used the CLI.
🚀 Manual Setup
1. Define your endpoints
[!IMPORTANT] The key prefix IS the HTTP method — this is mandatory, not a convention.
api-nexusreads the part before the first_in your key name to determine how to make the request. There is no separatemethodfield — the key name is your method.| Key prefix | HTTP method sent | |------------|-----------------| |
GET_| GET | |POST_| POST | |PUT_| PUT | |PATCH_| PATCH | |DELETE_| DELETE |✅
GET_USERS→ sends aGETrequest
✅POST_LOGIN→ sends aPOSTrequest
❌FETCH_USERS→ will NOT work —fetchis not a valid HTTP method
❌LOAD_DATA→ will NOT work — always start your key with a valid HTTP verb
// src/api/endpoints.ts
export const ENDPOINTS = {
GET_USERS: "users", // → GET /users
GET_USER: "users/{id}", // → GET /users/42
POST_LOGIN: "auth/login", // → POST /auth/login
POST_SIGNUP: "auth/signup", // → POST /auth/signup
PUT_PROFILE: "profile/{id}", // → PUT /profile/1
DELETE_POST: "posts/{id}", // → DELETE /posts/99
} as const;2. Create your API instance
// src/api/index.ts
import { createApiNexus } from "@niteen5/api-nexus";
import { ENDPOINTS } from "./endpoints";
export const api = createApiNexus({
baseUrl: process.env.NEXT_PUBLIC_API_URL ?? "",
endpoints: ENDPOINTS,
httpClient: "fetch", // "fetch" (default) | "axios"
getToken: () => localStorage.getItem("token"), // optional
});3. Call your API
const result = await api.call<User[]>("GET_USERS");
if (result.isSuccess) {
console.log(result.data); // typed as User[]
} else {
console.error(result.message, result.status);
}📖 Usage Examples
GET with query params
const result = await api.call<User[]>("GET_USERS", {
queryParams: { page: 1, limit: 10, search: "john" },
});GET with path params
const result = await api.call<User>("GET_USER", {
params: { id: "42" },
});
// Calls: GET /users/42POST with a body
const result = await api.call<{ token: string }>("POST_LOGIN", {
payload: { email: "[email protected]", password: "secret" },
});PUT / PATCH / DELETE
The HTTP method is inferred from the prefix of your endpoint key:
| Key prefix | HTTP method |
|------------|-------------|
| GET_ | GET |
| POST_ | POST |
| PUT_ | PUT |
| PATCH_ | PATCH |
| DELETE_ | DELETE |
await api.call("PUT_PROFILE", { params: { id: "1" }, payload: { name: "Niteen" } });
await api.call("DELETE_POST", { params: { id: "99" } });Pass extra fetch/axios config
const result = await api.call<Blob>("GET_USERS", {
config: { cache: "no-store" }, // Standard RequestInit options
});⚙️ Configuration Reference
createApiNexus({
baseUrl: string, // Required — your API base URL
endpoints: Record<string, string>, // Required — your endpoint map
httpClient: "fetch" | "axios", // Optional — default: "fetch"
getToken: () => string | null, // Optional — for Authorization header
})📬 Response Shape
Every api.call() call returns a consistent, typed IResponseFormat<T>:
interface IResponseFormat<T> {
isSuccess: boolean;
data?: T;
error?: unknown;
message?: string;
status?: number;
}You never need to write a try/catch — errors are caught internally and always returned as { isSuccess: false, message, status }.
🔌 Using with React
// hooks/useUsers.ts
import { useEffect, useState } from "react";
import { api } from "../api";
export function useUsers() {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
api.call<User[]>("GET_USERS").then((res) => {
if (res.isSuccess && res.data) setUsers(res.data);
setLoading(false);
});
}, []);
return { users, loading };
}⚡ Using with Next.js
// app/users/page.tsx (Next.js App Router — Server Component)
import { createApiNexus } from "@niteen5/api-nexus";
import { ENDPOINTS } from "@/api/endpoints";
const api = createApiNexus({
baseUrl: process.env.API_URL!,
endpoints: ENDPOINTS,
httpClient: "fetch",
// No getToken needed on the server — pass the token per-request via config:
});
export default async function UsersPage() {
const result = await api.call<User[]>("GET_USERS", {
config: { next: { revalidate: 60 } } as RequestInit, // Next.js ISR
});
if (!result.isSuccess) return <p>Error: {result.message}</p>;
return <ul>{result.data?.map((u) => <li key={u.id}>{u.name}</li>)}</ul>;
}🔄 Switching Between fetch and axios
// Using native fetch (default — no extra install needed)
const api = createApiNexus({ baseUrl, endpoints, httpClient: "fetch" });
// Using axios (run: npm install axios)
const api = createApiNexus({ baseUrl, endpoints, httpClient: "axios" });Both adapters produce the same IResponseFormat<T> response, so your application code never changes.
🧑💻 TypeScript Support
The library is written entirely in TypeScript and ships its own type definitions — no @types/ package needed.
Your endpoint keys are typed automatically:
api.call("INVALID_KEY"); // ❌ TypeScript error — not in your endpoints map
api.call("GET_USERS"); // ✅📄 License
MIT © Niteen Kumar
