A TypeScript-first, decorator-based HTTP client for building elegant and modular API clients with fetch under the hood. Inspired by Spring's `@RestClient` and OpenFeign.
npm install @bytekit/autofetchA TypeScript-first, decorator-based HTTP client for building elegant and modular API clients with fetch under the hood. Inspired by Spring's @RestClient and OpenFeign.
- ๐งฉ Class-based HTTP client with decorators
- ๐ฏ Supports GET, POST, PUT, PATCH, DELETE, and more
- โ๏ธ Middleware support via interceptors
- ๐ Caching support and hooks for before/after execution
- ๐งต Works with native fetch and streams/blobs
- ๐งช Fully typed and extensible
``bash`
npm install @bytekit/autofetch`
orbash`
yarn add @bytekit/autofetch
`ts
import {
Client,
GetMapping,
PostMapping,
BodyParam,
PathParam,
QueryParam,
} from "@bytekit/autofetch";
interface User {
id: string;
name: string;
email: string;
}
@Client({
baseUrl: () => "https://api.example.com",
before: (self, url, init, id) => {
console.log([${id}] Requesting ${init.method} ${url} ${init.body});[${id}] Got response
},
after: (self, response, id) => {
console.log(, response);
},
})
class UserService {
@GetMapping({ value: "/users" })
async getUsers(): Promise
return [];
}
@GetMapping({ value: "/users/:id" })
async getUser(@PathParam("id") id: string): Promise
return {} as User;
}
@PostMapping({ value: "/users" })
async createUser(@BodyParam user: Omit
return {} as User;
}
@GetMapping({ value: "/users/search" })
async searchUsers(
@QueryParam("q") query: string,
@QueryParam({ name: "limit", required: false }) limit?: number
): Promise
return [];
}
}
// Usage
const service = new UserService();
const run = async () => {
const newUser = await service.createUser({
name: "Alice",
email: "alice@example.com",
});
const user = await service.getUser(newUser.id);
const users = await service.getUsers();
const searchResults = await service.searchUsers("ali", 10);
};
`
@Client(options)
Marks a class as an API client.
- @GetMapping({ value })@PostMapping({ value })
- @PutMapping({ value })
- @PatchMapping({ value })
- @DeleteMapping({ value })
-
- @BodyParam โ binds the request body@PathParam(name)
- โ binds a URL path parameter@QueryParam(name | { name, required })
- โ binds query parameters@HeaderParam(name)
- โ binds a header@FormParam(name)
- โ binds form fields (for multipart/form-data)@URLEncodedFormParam(name)
- โ binds form fields (for application/x-www-form-urlencoded)@Init
- โ accesses the RequestInit object for dynamic tweaking
- Interceptors: inject RequestInit at the client or method levelbefore
- Hooks: and after functions for logging, auth, etc.stream: true
- Streaming: on @Mapping returns the raw response streamblob: true` for binary payloads
- Blobs:
- Custom Fetch: swap in your own fetch implementation