docs/docs/en/plugin-development/client/request.md
NocoBase provides an APIClient based on Axios that can be used to make HTTP requests from anywhere you can get a Context.
Common locations where you can get Context include:
app.contextengine.contextplugin.contextmodel.contextctx.api.request() is the most commonly used method to make requests. Its parameters and return values are identical to axios.request().
request<T = any, R = AxiosResponse<T>, D = any>(
config: AxiosRequestConfig<D>,
): Promise<R>;
Basic Usage
await ctx.api.request({
url: 'users:list',
method: 'get',
});
You can use standard Axios request configurations directly:
await ctx.api.request({
url: 'users:create',
method: 'post',
data: {
name: 'Tao Tao',
},
});
ctx.api.axios is an AxiosInstance instance through which you can modify global default configurations or add request interceptors.
Modify Default Configuration
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
For more available configurations, see Axios Default Config.
Interceptors can process requests before they are sent or responses after they return. For example, consistently adding request headers, serializing parameters, or displaying unified error messages.
// Use qs to serialize params
axios.interceptors.request.use((config) => {
config.paramsSerializer = (params) =>
qs.stringify(params, {
strictNullHandling: true,
arrayFormat: 'brackets',
});
return config;
});
// Custom request headers
axios.interceptors.request.use((config) => {
config.headers['Authorization'] = `Bearer token123`;
config.headers['X-Hostname'] = 'localhost';
config.headers['X-Timezone'] = '+08:00';
config.headers['X-Locale'] = 'zh-CN';
config.headers['X-Role'] = 'admin';
config.headers['X-Authenticator'] = 'basic';
config.headers['X-App'] = 'sub1';
return config;
});
axios.interceptors.response.use(
(response) => response,
(error) => {
// Show unified notification when request fails
ctx.notification.error({
message: 'Request response error',
});
return Promise.reject(error);
},
);
The following are custom request headers supported by NocoBase Server, which can be used for multi-app, internationalization, multi-role, or multi-authentication scenarios.
| Header | Description |
|---|---|
X-App | Specify the current accessed app in multi-app scenarios |
X-Locale | Current language (e.g., zh-CN, en-US) |
X-Hostname | Client hostname |
X-Timezone | Client timezone (e.g., +08:00) |
X-Role | Current role |
X-Authenticator | Current user authentication method |
💡 Tip
These request headers are usually automatically injected by interceptors and don't need to be set manually. Only in special scenarios (such as test environments or multi-instance scenarios) do you need to add them manually.
In React components, you can get the context object through useFlowContext() and then call ctx.api to make requests.
import { useFlowContext } from '@nocobase/client';
const MyComponent = () => {
const ctx = useFlowContext();
const fetchData = async () => {
const response = await ctx.api.request({
url: '/api/posts',
method: 'get',
});
console.log(response.data);
};
useEffect(() => {
fetchData();
}, []);
return <div>Loading...</div>;
};
In actual development, you can use ahooks' useRequest Hook to more conveniently handle the request lifecycle and state.
import { useFlowContext } from '@nocobase/client';
import { useRequest } from 'ahooks';
const MyComponent = () => {
const ctx = useFlowContext();
const { data, loading, error, refresh } = useRequest(() =>
ctx.api.request({
url: 'posts:list',
method: 'get',
}),
);
if (loading) return <div>Loading...</div>;
if (error) return <div>Request error: {error.message}</div>;
return (
<div>
<button onClick={refresh}>Refresh</button>
<pre>{JSON.stringify(data?.data, null, 2)}</pre>
</div>
);
};
This approach makes request logic more declarative, automatically managing loading states, error handling, and refresh logic, which is very suitable for use in components.