Main Function#
createFetch()#
Creates a type-safe fetch function for your API.
Parameters:
apis- An object mapping API paths to their schema definitionsbaseUrl- The base URL for all API requestssharedInit(optional) - Shared RequestInit options that will be merged with per-request options
Returns: A typed fetch function that accepts:
path- The API path (must be a key from your schema)options(optional) - Request options (params, query, body) based on the path's schemainit(optional) - Per-request RequestInit to customize the fetch request (merged with sharedInit)
Example:
Type Definitions#
ApiSchema#
Schema definition for an API. Maps API paths to their schema definitions.
Each path in your schema can have:
params- Schema for URL path parameters (e.g.,:id)query- Schema for query string parametersbody- Schema for request body (automatically sets method to POST)response- Schema for response validation
Important: If your path contains parameters (e.g., /users/:id), you must define a params schema. Attempting to use a parameterized path without a params schema will throw an error at runtime.
Example:
ApiPath<T>#
Extract valid API paths from an API schema.
Example:
FetchOptions<T, Path>#
Extract the required fetch options for a specific API path.
Automatically infers the correct types for params, query, and body based on the schema definition for the given path.
Example:
ApiData<Schemas, Path, Option>#
Extract the inferred data type for a specific schema option from an API path.
This is a flexible type that extracts the inferred TypeScript type for any schema option ('params', 'query', 'body', or 'response') from a specific API path. This replaces the older ApiResponse type and provides more flexibility for working with different parts of your API schema.
Parameters:
Schemas- The complete API schema typePath- The specific API path to extract fromOption- The schema option to extract ('params','query','body', or'response')
Examples:
Note: For backward compatibility, you can create a type alias:
Request Validation#
what-the-fetch automatically validates all request data (params, query, and body) as well as response data using the schemas you provide. The validation happens concurrently for optimal performance.
Validation Behavior#
- Params validation: If your path contains parameters (e.g.,
/users/:id), you must provide aparamsschema. The library will throw an error if a parameterized path is missing a params schema. - Query validation: Query parameters are validated if a
queryschema is provided. - Body validation: Request body is validated if a
bodyschema is provided. - Response validation: Response data is validated if a
responseschema is provided. - Concurrent validation: All request validations (params, query, body) run concurrently using
Promise.all()for better performance.
Validation Errors#
When validation fails, the library throws an error with details about the validation issues:
Required Params Schema#
If your path contains URL parameters, you must define a params schema:
The library detects parameterized paths using the pattern /:paramName and will throw this error if no params schema is found:
Request Examples#
GET Request with Path Parameters#
GET Request with Query Parameters#
GET Request with Both Path and Query Parameters#
POST Request with Body#
Custom Headers and Options#
HTTP Methods#
what-the-fetch automatically infers HTTP methods based on the presence of a request body. You can optionally use the @method prefix for explicit control or to specify methods other than GET and POST.
Automatic Method Inference#
By default, what-the-fetch infers the HTTP method:
- Requests with a body →
POST - Requests without a body →
GET
Method Prefix Syntax (Optional)#
For explicit control or to use other HTTP methods, add the @method prefix:
Note: /users/:id and @get/users/:id are completely equivalent and both result in a GET request.
Supported HTTP Methods#
All standard HTTP methods are supported:
@get- GET requests (retrieve data)@post- POST requests (create new resources)@put- PUT requests (replace existing resources)@patch- PATCH requests (partially update resources)@delete- DELETE requests (remove resources)@head- HEAD requests (retrieve headers only)@options- OPTIONS requests (check available methods)
Complete Example#
Equivalence Examples#
The following path definitions are equivalent:
Method inference rules:
- Request has a
body→POST - Request has no
body→GET - Method prefix specified → Uses that method
Method Prefix with Path Parameters#
The method prefix works seamlessly with path parameters:
Case Insensitive#
Method prefixes are case-insensitive and converted to uppercase:
Best Practices#
- Be explicit with methods: Use method prefixes for clarity, especially for PUT, PATCH, and DELETE operations
- RESTful design: Follow REST conventions:
@getfor retrieval@postfor creation@putfor full replacement@patchfor partial updates@deletefor removal
- Consistency: Choose either to always use method prefixes or rely on automatic detection - be consistent across your API schema
Advanced Usage#
Shared Request Configuration#
Use the third parameter of createFetch() to set shared options for all requests:
Multiple Endpoints with Shared Schemas#
Building a Complete API Client#
Standard Schema Support#
what-the-fetch works with any schema library that implements Standard Schema:
Zod#
Valibot#
ArkType#
Error Handling#
HTTP Errors#
what-the-fetch automatically throws an error for non-2xx status codes:
Validation Errors#
Schema validation errors are thrown when response doesn't match the schema:
TypeScript Features#
Full Type Inference#
Autocomplete Support#
When using what-the-fetch in TypeScript, you get full autocomplete for:
- Available API paths
- Required options (params, query, body)
- Field names and types
- Response properties
Compile-Time Validation#
Performance Considerations#
what-the-fetch is designed to be performant:
- Small bundle size: Minimal dependencies (only fast-url for URL building and Standard Schema spec)
- Efficient URL building: Leverages fast-url library's optimized implementation
- Type-level computation: Most type checking happens at compile time
- Runtime validation: Only validates responses, not TypeScript types
Bundle Size#
what-the-fetch adds minimal overhead to your bundle:
- Core library: ~2KB minified + gzipped
- Plus your choice of schema library (Zod, Valibot, etc.)
Browser and Runtime Compatibility#
what-the-fetch works in all modern JavaScript environments:
- ✅ Node.js 18+
- ✅ Bun
- ✅ Deno
- ✅ Modern browsers (Chrome, Firefox, Safari, Edge)
- ✅ React Native
- ✅ Electron
Requirements:
fetchAPI support (built-in in modern environments)- Standard Schema-compatible validation library