Getting Started
An APIful client is a set of default fetch options – a base URL, headers, retries – plus the extensions you add to it. The extensions decide how you write a request and how much of it TypeScript knows: plain fetch-style calls, a chain of path segments, or paths and responses typed from an OpenAPI schema.
Start with one of the built-in extensions, or write your own. Either way the client stays one callable object, which is how extensions work.
Installation
Get started by installing apiful in your project:
pnpm add apifulyarn add apifulnpm install apifulTIP
Your API client ships with your application, so apiful belongs in dependencies. Only the schema tooling it calls during type generation – openapi-typescript and json-schema-to-typescript-lite – is a development dependency.
Your First API Client
Start by creating your first API client with a base URL and authorization headers:
import { createClient } from 'apiful'
const client = createClient({
baseURL: 'https://api.example.com',
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
})NOTE
createClient returns an ApiClient that cannot make requests yet – calling it throws a TypeError until you add a handler extension.
Add a Handler Extension
ofetchBuilder wraps ofetch and is the shortest way to a working client. It is one of three built-in extensions, which differ in how you write a request – pick another one later if it suits your API better.
Add it to your client with the with method:
import { createClient, ofetchBuilder } from 'apiful'
const client = createClient({
baseURL: 'https://api.example.com',
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
})
.with(ofetchBuilder())Your client can now make HTTP requests:
// GET request to https://api.example.com/users/1
const user = await client('users/1', { method: 'GET' })
// POST request with JSON body
const newUser = await client('users', {
method: 'POST',
body: { name: 'John Doe', email: 'john@example.com' }
})Each request inherits the client's default options and can override them individually. JSON serialization, response parsing, and thrown errors for non-2xx responses come from ofetch.
TIP
If your API publishes an OpenAPI schema, the OpenAPI extension types paths, bodies, and responses for you from that schema.
Chaining Extensions
A client can carry more than one extension. Chain with calls to add them:
const client = createClient({ baseURL: 'https://api.example.com' })
// Handler extension: makes the client callable
.with(ofetchBuilder())
// Methods extension: adds `logDefaults()`
.with(logExtension)See Custom Extensions for how logExtension is written, and how extensions work for what happens when two of them collide.