APIful
APIful provides a unified interface to manage all your API interactions by setting up a client with default fetch options, such as the base API URL and headers. Extensions add a variety of features to the client to match your favorite flavor of API management.
You can use one of the built-in extensions to get started right away, or create your own custom extension to meet your specific needs.
Setup
[!TIP] 📖 Read the documentation
# pnpm
pnpm add -D apiful
# npm
npm i -D apiful
Usage
[!TIP] 📖 Read the documentation
Your First API Client
Create your first API client by initialising it with a base URL and a sample bearer token for authorization:
import { createClient } from 'apiful'
const client = createClient({
baseURL: 'https://api.example.com',
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
},
})
[!NOTE] The
createClient
function returns anApiClient
instance that does not yet have a call signature. You will need to add a base extension to the client in order to make API requests. Read on to learn how to do this.
Built-in Extensions
### ofetchBuilder
ts
import { createClient, ofetchBuilder } from 'apiful'
const baseURL = 'https://api.example.com'
const adapter = ofetchBuilder()
const api = createClient({ baseURL }).with(adapter)
// GET request to <baseURL>/users/1
await api('users/1', { method: 'GET' })
| What it does: The ofetchBuilder wraps ofetch to handle API requests.
|
### apiRouterBuilder
ts
import { apiRouterBuilder, createClient } from 'apiful'
const baseURL = 'https://api.example.com'
const adapter = apiRouterBuilder()
const api = createClient({ baseURL }).with(adapter)
// GET request to <baseURL>/users/1
await api.users.get(1)
// POST request to <baseURL>/users with payload
await api.users.post({ name: 'foo' })
| What it does: The apiRouterBuilder provides a jQuery-like and Axios-esque API for building and making API requests. It allows you to construct your API calls in a declarative way.
|
### OpenAPIBuilder
ts
import { createClient, OpenAPIBuilder } from 'apiful'
const baseURL = 'https://petstore3.swagger.io/api/v3'
// Pass pre-generated schema type ID to adapter
const adapter = OpenAPIBuilder<'petStore'>()
const api = createClient({ baseURL }).with(adapter)
// Typed parameters and response
const response = await api('/user/{username}', {
method: 'GET',
path: { username: 'user1' },
})
| What it does: If your API has an OpenAPI schema, APIful can use it to generate types for you, which the OpenAPIBuilder extension then consumes to provide type-safe API calls.
For example, the response returned by the API call on the left is typed as follows:
ts
const response: {
id?: number
username?: string
// …
}
Follow the OpenAPI extension documentation to learn more about how to generate TypeScript definitions from your OpenAPI schema files.
|
Custom Extensions
Each client can have more than one extension. This means that you can chain with
methods to add multiple extensions to your client.
For example, you can add a custom extension to log the default fetch options:
import type { MethodsExtensionBuilder } from 'apiful'
const logExtension = (client => ({
logDefaults() {
console.log('Default fetch options:', client.defaultOptions)
}
})) satisfies MethodsExtensionBuilder
const extendedClient = client
.with(logExtension)
extendedClient.logDefaults() // { baseURL: 'https://api.example.com', headers: { Authorization: 'Bearer <your-bearer-token>' } }
If you have specific requirements that are not covered by the included extensions, you can create your own extensions. Follow the Custom Extensions guide to learn more.
Development
- Clone this repository
- Install latest LTS version of Node.js
- Enable Corepack using
corepack enable
- Install dependencies using
pnpm install
- Run interactive tests using
pnpm test
License
Made with 💛
Published under MIT License.