@ryzes/rio
Version:
Axios wrapper for handling { code, message, data } responses and integrating with TanStack React Query.
276 lines (203 loc) • 7.59 kB
Markdown
⚠️ **IMPORTANT**: This library does not support HTTP status code 3xx redirects. Only 2xx success responses and 4xx/5xx error responses are properly handled.
Rio is a TypeScript library that provides an Axios wrapper for handling standardized `{ code, message, data }` API responses and integrates seamlessly with TanStack React Query.
```bash
pnpm add @ryzes/rio
npm install @ryzes/rio
yarn add @ryzes/rio
```
```typescript
import { httpClient } from '@ryzes/rio';
httpClient.initialize({
baseURL: 'https://api.example.com',
timeout: 10000,
successCode: 0,
});
```
```typescript
import { QueryClientProvider } from '@tanstack/react-query';
import { createRioQueryClient } from '@ryzes/rio';
import { httpClient } from '@ryzes/rio';
// Initialize HTTP client
httpClient.initialize({
baseURL: 'https://api.example.com'
});
// Create React Query client with error handling
const queryClient = createRioQueryClient((title: string, info: string) => {
// Handle errors globally
console.error('Error:', title, info);
});
export default function App() {
return (
<QueryClientProvider client={queryClient}>
{/* Your app components */}
</QueryClientProvider>
);
}
```
```typescript
import { useQuery } from '@tanstack/react-query';
import { httpClient } from '@ryzes/rio';
// In your React component
const MyComponent = () => {
const { data, isLoading, error } = useQuery({
queryKey: ['userData'],
queryFn: async () => {
// Directly use httpClient.get()
return httpClient.get<{ name: string; age: number }>('/users/1');
},
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {(error as Error).message}</div>;
return <div>Hello, {data?.name}!</div>;
};
// Custom error handling with skipGlobalError
const MyComponentWithCustomErrorHandling = () => {
const { data, isLoading, error } = useQuery({
queryKey: ['userData'],
queryFn: async () => {
// Skip global error handling to handle errors yourself
return httpClient.get('/users/1', { meta: { skipGlobalError: true } });
},
});
if (isLoading) return <div>Loading...</div>;
if (error) {
// Handle error yourself instead of using global error handler
return <div>Custom error message: {(error as Error).message}</div>;
}
return <div>Hello, {data?.name}!</div>;
};
```
```typescript
import { ConsoleAuthService } from '@ryzes/rio';
// Initialize with authentication service
httpClient.initialize({
baseURL: 'https://api.example.com',
authService: new ConsoleAuthService(),
});
// Login and token handling
interface LoginResponse {
token: string;
}
const loginResponse = await httpClient.post<LoginResponse>('/auth/login', {
username: 'your-username',
password: 'your-password'
});
// Set the authentication token
httpClient.setAuthToken(loginResponse.token);
// Get the current token
const currentToken = httpClient.getAuthToken();
// Clear the token
httpClient.clearAuthToken();
```
- `httpClient` - Pre-configured HTTP client instance
- `createRioQueryClient(errorReporter: (title: string, info: string) => void)` - Creates React Query client with built-in error handling
The `httpClient` instance provides the following HTTP methods:
- `get(url: string, config?: AxiosRequestConfig)` - GET request
- `post(url: string, data: any, config?: AxiosRequestConfig)` - POST request
- `put(url: string, data: any, config?: AxiosRequestConfig)` - PUT request
- `patch(url: string, data: any, config?: AxiosRequestConfig)` - PATCH request
- `delete(url: string, config?: AxiosRequestConfig)` - DELETE request
- `setAuthToken(token: string)` - Set authentication token
- `getAuthToken(): string | null` - Get current authentication token
- `clearAuthToken()` - Clear authentication token
The library also provides raw response methods that return the complete `{ code, message, data }` structure:
- `getRaw(url: string, config?: AxiosRequestConfig)` - GET request returning raw response
- `postRaw(url: string, data: any, config?: AxiosRequestConfig)` - POST request returning raw response
- `putRaw(url: string, data: any, config?: AxiosRequestConfig)` - PUT request returning raw response
- `patchRaw(url: string, data: any, config?: AxiosRequestConfig)` - PATCH request returning raw response
- `deleteRaw(url: string, config?: AxiosRequestConfig)` - DELETE request returning raw response
```typescript
const result = await httpClient.get('/api/users');
```
```typescript
const rawResponse = await httpClient.getRaw<{ name: string; age: number }>('/api/users/1');
// rawResponse will be: { code: 0, message: 'success', data: { name: 'John', age: 30 } }
// Example with server returning {code:200,message:"ok",data:{result:true}}
const rawResponse = await httpClient.getRaw('/api/example');
// Returns: { code: 200, message: "ok", data: { result: true } }
```
```typescript
const newUser = await httpClient.post('/api/users', {
name: 'John Doe',
email: 'john@example.com'
});
```
```typescript
const rawResponse = await httpClient.postRaw('/api/users', {
name: 'John Doe',
email: 'john@example.com'
});
// rawResponse will be: { code: 0, message: 'success', data: { id: 1, name: 'John', email: 'john@example.com' } }
```
**Regular methods** (get, post, put, patch, delete) return only the `data` field from the response:
```typescript
// Server returns: {code:200, message:"ok", data:{result:true}}
const result = await httpClient.get('/api/example');
// Returns: {result: true} (only the data field)
```
**Raw methods** (getRaw, postRaw, putRaw, patchRaw, deleteRaw) return the complete response structure:
```typescript
// Server returns: {code:200, message:"ok", data:{result:true}}
const rawResult = await httpClient.getRaw('/api/example');
// Returns: {code: 200, message: "ok", data: {result: true}} (complete response)
```
```typescript
const users = await httpClient.get('/api/users', {
params: { page: 1, limit: 10 }
});
```
```typescript
// Login
const response = await httpClient.post('/auth/login', {
username: 'testuser',
password: 'password123'
});
// Set token for future requests
httpClient.setAuthToken(response.token);
```
The library supports different authentication service implementations:
- `ConsoleAuthService` - For server-side rendering/console applications (stores tokens in memory)
- `DefaultAuthService` - For browser applications (stores tokens in localStorage)
- Custom services implementing the `AuthService` interface
## Advanced Usage
### Custom Success Code
```typescript
// If your API uses 200 instead of 0 for success
httpClient.initialize({
baseURL: 'https://api.example.com',
successCode: 200,
});
```
```typescript
import { toast } from 'sonner';
const queryClient = createRioQueryClient((title: string, info: string) => {
toast.error(info); // Show toast notification for errors
});
```
MIT © Ryzes