@kreisler/createapi
A modern, type-safe API client that uses JavaScript Proxies to create dynamic API endpoints. Build flexible API clients without defining every endpoint manually.
Installation
npm install @kreisler/createapi
Overview
@kreisler/createapi provides a proxy-based approach to creating API clients. Instead of manually defining each endpoint, you can access any endpoint dynamically through property access.
The package automatically handles URL construction, query parameters, and response parsing.
Basic Usage
Import the package
import { createApi } from '@kreisler/createapi' ;
Create an API instance
const api = createApi ( 'https://api.example.com' );
Make requests
// GET request to https://api.example.com/users
const users = await api . users ();
// GET request with ID: https://api.example.com/users/123
const user = await api . users ( '123' );
// GET request with query params: https://api.example.com/users?limit=10&offset=0
const paginatedUsers = await api . users ({ limit: 10 , offset: 0 });
API Reference
createApi
Creates a new API client instance with dynamic endpoint access.
function createApi < I >(
url : string ,
args ?: ArgsCreateApi
) : I
Optional configuration options Enable debug mode to return request metadata instead of making the actual request
Force JSON response parsing (default behavior)
Force text response parsing instead of JSON
Return the raw Response object instead of parsing
ArgsCreateApi Interface
interface ArgsCreateApi extends RequestInit {
x_debug ?: boolean ;
x_json ?: boolean ;
x_text ?: boolean ;
x_response ?: boolean ;
}
Extends the standard RequestInit interface, allowing you to pass any standard fetch options.
Advanced Examples
TypeScript with Type Safety
Define interfaces for your API endpoints:
interface PokeAPI {
pokemon : {
( options : { limit : number ; offset : number }) : Promise <{
count : number ;
next : string ;
previous : string ;
results : Array <{ name : string ; url : string }>;
}>;
( name : string ) : Promise <{ name : string ; id : number }>;
};
'pokemon-species' : ( name : string ) => Promise <{ name : string ; id : number }>;
type : ( id : number ) => Promise <{ name : string ; id : number }>;
}
const pokeapi : PokeAPI = createApi ( 'https://pokeapi.co/api/v2' );
// Fully typed requests
const pikachu = await pokeapi . pokemon ( 'pikachu' );
const pokemonList = await pokeapi . pokemon ({ limit: 20 , offset: 0 });
POST Requests
interface PostManAPI {
get : ( params ?: object ) => Promise <{ args : object ; headers : object ; url : string }>;
post : ( id ?: any , params ?: any , options ?: ArgsCreateApi ) => Promise < any >;
}
const postman : PostManAPI = createApi ( 'https://postman-echo.com' );
const response = await postman . post ( null , null , {
method: 'POST' ,
body: JSON . stringify ({ foo: 'bar' }),
headers: { 'Content-Type' : 'application/json' }
});
Debug Mode
Use debug mode to inspect request construction without making actual HTTP calls:
const api = createApi ( 'https://api.example.com' , { x_debug: true });
const debug = await api . users ({ limit: 10 });
console . log ( debug );
// {
// prop: 'users',
// path: 'https://api.example.com/users?limit=10',
// id: { limit: 10 },
// params: undefined,
// args: { x_debug: true },
// target: {},
// receiver: {}
// }
Working with Binary Data
Get raw Response objects for binary data:
import { writeFile } from 'fs/promises' ;
interface ImageAPI {
'img.jpg' : (
options : { w : number ; h : number ; tc : string ; bg : string ; t : string },
_ : null ,
__ : ArgsCreateApi
) => Promise < Response >;
}
const imageApi : ImageAPI = createApi ( 'https://via.assets.so' );
const response = await imageApi [ 'img.jpg' ](
{ w: 400 , h: 150 , tc: 'blue' , bg: '#cecece' , t: 'Create API' },
null ,
{ x_response: true }
);
const buffer = await response . arrayBuffer ();
await writeFile ( 'img.jpg' , Buffer . from ( buffer ));
Text Responses
const api = createApi ( 'https://api.example.com' , { x_text: true });
const htmlContent = await api . page ( 'about' );
Dynamic Endpoint Construction
Simple Path
With ID
With Query Params
Combined
const api = createApi ( 'https://api.example.com' );
await api . users (); // GET /users
const api = createApi ( 'https://api.example.com' );
await api . users ( '123' ); // GET /users/123
await api . users ( 123 ); // GET /users/123
const api = createApi ( 'https://api.example.com' );
await api . users ({ page: 1 , limit: 10 }); // GET /users?page=1&limit=10
const api = createApi ( 'https://api.example.com' );
// GET /users/123?include=posts
await api . users ( '123' , { include: 'posts' });
Built-in Demo URLs
The package includes several demo API URLs for testing:
import { DemoUrlsEnum , createApi } from '@kreisler/createapi' ;
// Available demo URLs:
// - DemoUrlsEnum.NEKOBOT
// - DemoUrlsEnum.POKEAPI
// - DemoUrlsEnum.POSTMAN
// - DemoUrlsEnum.ANIMEFLV_KUDASAI
// - DemoUrlsEnum.FRASEDELDIA
// - DemoUrlsEnum.ADVICE
// - DemoUrlsEnum.DECAPI
const pokeapi = createApi ( DemoUrlsEnum . POKEAPI );
const pokemon = await pokeapi . pokemon ( 'ditto' );
Error Handling
The package throws errors for failed HTTP requests. Always use try-catch or promise error handling.
try {
const api = createApi ( 'https://api.example.com' );
const data = await api . users ( '123' );
} catch ( error ) {
if ( error . message . includes ( 'Request failed with status' )) {
console . error ( 'HTTP Error:' , error . message );
} else if ( error . message . includes ( 'Error parsing response' )) {
console . error ( 'JSON Parse Error' );
}
}
Features
Proxy-based Dynamic Endpoints
Access any endpoint through property notation without pre-defining routes. The package automatically constructs URLs based on property access.
Flexible Parameter Handling
Pass objects as query parameters
Pass strings/numbers as path segments
Combine both in a single call
Automatic URLSearchParams encoding
Multiple Response Formats
Full TypeScript support with generics for type-safe API clients.
Inspect request construction without making actual HTTP calls.
Type Exports
import type {
ArgsCreateApi ,
DebugResponse ,
ExampleUrl ,
DemoUrlsEnum
} from '@kreisler/createapi' ;
License
MIT License - see the LICENSE file for details.
Links