@kreisler/createapi
Create dynamic API instances that automatically generate endpoints using JavaScript Proxy. Simplifies API consumption by providing a flexible, type-safe interface for making HTTP requests.
Installation
npm install @kreisler/createapi
Core Function
createApi
Creates a dynamic API proxy that automatically generates endpoints based on property access.
The base URL for the API. Can be a string or URL object.
Optional configuration object for request initialization and behavior. Enable debug mode to return request information instead of making actual requests.
Force JSON response parsing.
Force text response parsing.
Return the raw Response object instead of parsing.
All standard RequestInit properties (headers, method, body, etc.) are also supported.
Returns a proxied API instance with the generic type I defining available endpoints.
Type Definitions
ArgsCreateApi
Extends RequestInit with additional control flags.
interface ArgsCreateApi extends RequestInit {
x_debug ?: boolean | undefined
x_json ?: boolean | undefined
x_text ?: boolean | undefined
x_response ?: boolean | undefined
}
DebugResponse
Returned when x_debug is enabled.
interface DebugResponse {
prop : string
path : string
id : string | number | object | undefined | null
params : string | string [][] | undefined
args : ArgsCreateApi
target : object
receiver : object
}
DemoUrlsEnum
Pre-configured demo API URLs for testing.
enum DemoUrlsEnum {
NEKOBOT = 'https://nekobot.xyz/api' ,
POKEAPI = 'https://pokeapi.co/api/v2' ,
POSTMAN = 'https://postman-echo.com' ,
ANIMEFLV_KUDASAI = 'https://www3.animeflv.net' ,
FRASEDELDIA = 'https://frasedeldia.azurewebsites.net/api' ,
ADVICE = 'https://api.adviceslip.com' ,
DECAPI = 'https://decapi.me'
}
Usage Examples
Basic Pokemon API
import { createApi , DemoUrlsEnum } from '@kreisler/createapi'
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 ( DemoUrlsEnum . POKEAPI )
// Fetch specific Pokemon
const pikachu = await pokeapi . pokemon ( 'pikachu' )
console . log ( pikachu )
// Fetch with query parameters
const list = await pokeapi . pokemon ({ limit: 20 , offset: 0 })
console . log ( list . results )
Postman Echo API
import { createApi , DemoUrlsEnum } from '@kreisler/createapi'
interface PostMan {
get : ( id ?: string | number | object , params ?: object , extraparams ?: RequestInit ) =>
Promise <{ args : object , headers : object , url : string }>
post : ( id ?: string | number | object , params ?: object , extraparams ?: RequestInit ) =>
Promise <{ args : object , headers : object , url : string }>
}
const postMan : PostMan = createApi ( DemoUrlsEnum . POSTMAN )
const get = await postMan . get ()
const post = await postMan . post ()
console . log ( get , post )
Image Placeholder with Raw Response
import { createApi , type ArgsCreateApi } from '@kreisler/createapi'
import { writeFile } from 'fs/promises'
const imageplaceholder = createApi <{
'img.jpg' : (
options : { w : number , h : number , tc : string , bg : string , t : string },
_ : null ,
__ : ArgsCreateApi
) => Promise < Response >
}>( 'https://via.assets.so' )
const data = await imageplaceholder [ 'img.jpg' ](
{ w: 400 , h: 150 , tc: 'blue' , bg: '#cecece' , t: 'Create API' },
null ,
{ x_response: true }
)
const buffer = await data . arrayBuffer ()
await writeFile ( 'img.jpg' , Buffer . from ( buffer ), { encoding: 'binary' })
Debug Mode
import { createApi , type DebugResponse } from '@kreisler/createapi'
const api = createApi ( 'https://api.example.com' , { x_debug: true })
const debugInfo : DebugResponse = await api . users ( '123' )
console . log ( debugInfo . path ) // 'https://api.example.com/users/123'
console . log ( debugInfo . prop ) // 'users'
console . log ( debugInfo . id ) // '123'
import { createApi } from '@kreisler/createapi'
const api = createApi ( 'https://api.example.com' , {
headers: {
'Authorization' : 'Bearer token123' ,
'Content-Type' : 'application/json'
}
})
const user = await api . users ( '123' )
Force Text Response
import { createApi } from '@kreisler/createapi'
const api = createApi ( 'https://api.example.com' )
const html : string = await api . page ( 'about' , null , { x_text: true })
console . log ( html )
How It Works
The createApi function uses JavaScript Proxy to intercept property access and automatically construct API endpoints:
Property Access : Accessing api.users creates the path /users
Function Call : Calling api.users('123') adds the ID to the path: /users/123
Query Parameters : Passing an object as the first argument creates query strings
Extra Parameters : Third argument allows per-request configuration
Path Construction
Simple path : api.users → GET /users
With ID : api.users('123') → GET /users/123
With query params : api.users({ limit: 10 }) → GET /users?limit=10
With ID and params : api.users('123', { include: 'posts' }) → GET /users/123?include=posts
Error Handling
The library throws errors for failed requests:
try {
const data = await api . users ( 'invalid-id' )
} catch ( error ) {
console . error ( error . message ) // "Request failed with status 404: Not Found"
}