forgequery
v1.0.1
Published
npm install forgequery axios @tanstack/react-query
Maintainers
Readme
Installation
Using npm
npm install forgequery axios @tanstack/react-query
Using yarn
yarn add forgequery axios @tanstack/react-query
Project Setup
Wrap your app with ApiProvider to enable React Query:
// main.tsx / App.tsx
import React from 'react'
import { ApiProvider } from 'forgequery'
import { YourApp } from './YourApp'
export const App = () => (
<ApiProvider>
<YourApp />
</ApiProvider>
)Create an API Client
* createApiClient allows:
* Access token injection
* Automatic refresh on 401
* Expiration check
* Safe headersimport { createApiClient } from 'forgequery'
import {
getAccessToken,
refreshAccessToken,
setAccessToken,
clearAccessToken,
isTokenExpired,
} from './tokenManager'
export const api = createApiClient({
baseURL: 'https://api.example.com/v1',
getAccessToken,
refreshAccessToken,
setAccessToken,
clearAccessToken,
isTokenExpired,
})useApiQuery
Fetch data with React Query integration:
import { useApiQuery } from 'forgequery'
interface User {
id: string
name: string
}
const Users = () => {
const { data, isLoading, error } = useApiQuery<User[]>({
key: ['users'],
url: '/users',
api,
options: {
params: { page: 1 },
staleTime: 1000 * 60 * 10,
alwaysRefetchKeys: [['profile']],
},
})
if (isLoading) return <p>Loading...</p>
if (error) return <p>Error: {error.message}</p>
return (
<ul>
{data?.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}useApiQuery Options
enabled (boolean, default: true) — Enable / disable query
refetchInterval (number, default: undefined) — Auto refetch interval
retry (number, default: 1) — Number of retry attempts
staleTime (number, default: 300000) — Cache duration in milliseconds
params (Record<string, unknown>, default: {}) — Query params for GET request
headers (Record<string,string>, default: {}) — Custom headers
alwaysRefetchKeys (QueryKey[], default: []) — Keys to always bypass cache
useApiMutation
Send data with React Query mutation:
import { useApiMutation } from 'forgequery'
interface CreateUserPayload {
name: string
}
const CreateUserButton = () => {
const mutation = useApiMutation({
url: '/users',
method: 'POST',
api,
invalidateKeys: [['users']],
onSuccess: (data) => console.log('User created', data),
})
return <button onClick={() => mutation.mutate({ name: 'Jane Doe' })}>
Create User
</button>
}useApiMutation Options
url (string or function, default: -) — Endpoint URL (can be a dynamic function that receives variables)
method (POST | PUT | PATCH | DELETE, default: POST) — HTTP method for the request
api (AxiosInstance, default: -) — The Axios client to use for the request
headers (Record<string,string>, default: {}) — Custom headers to include in the request
invalidateKeys (QueryKey[], default: []) — Queries to invalidate after a successful mutation
onSuccess (function, default: -) — Callback executed after a successful mutation
onError (function, default: -) — Callback executed if the mutation fails
Dynamic URL Example
const deleteUser = useApiMutation<void, { id: string }>({
url: (vars) => `/users/${vars.id}`,
method: 'DELETE',
api,
invalidateKeys: [['users']],
})createQueryClient (Optional)
You can customize your React Query client:
import { createQueryClient } from 'forgequery'
const queryClient = createQueryClient()ApiProvider
Wrap your app to provide React Query context:
import { ApiProvider } from 'forgequery'
export const App = () => (
<ApiProvider>
<YourApp />
</ApiProvider>
)Example Full Component
import React from 'react'
import { useApiQuery, useApiMutation, ApiProvider } from 'forgequery'
import { api } from './apiClient'
const Users = () => {
const { data, isLoading } = useApiQuery<{ id: string; name: string }[]>({
key: ['users'],
url: '/users',
api,
})
const createUser = useApiMutation<{ id: string; name: string }, { name: string }>({
url: '/users',
api,
invalidateKeys: [['users']],
})
return (
<>
<button onClick={() => createUser.mutate({ name: 'Jane Doe' })}>
Create User
</button>
{isLoading ? 'Loading...' : data?.map(u => <p key={u.id}>{u.name}</p>)}
</>
)
}
export const App = () => (
<ApiProvider>
<Users />
</ApiProvider>
)Environment
* TypeScript
* React 18+
* React Query v5+
* Axios 1+
* Optional SSR (Next.js)Tips
* Always wrap app with ApiProvider
* Use invalidateKeys to auto-refresh related queries
* Dynamic URLs are supported for mutations
* Use alwaysRefetchKeys to bypass cache for sensitive data