API Integration
In VEF applications, request handling usually follows a clear path:
- create a global client with
starter.createApiClient() - define domain APIs with
apiClient.createQueryFn()andapiClient.createMutationFn() - call them through
useQuery()anduseMutation()inside components - use
fetchQuery()andexecuteMutation()outside React component scope
Create a Global apiClient
import { createApiClient } from "@vef-framework-react/starter";
export const apiClient = createApiClient({
http: {
baseUrl: "/api",
okCode: 0,
tokenExpiredCode: 1002,
timeout: 30_000,
async refreshToken(tokens) {
return await apiClient.executeMutation({
mutationFn: refreshAuth,
params: tokens
});
}
}
});
Define Query Functions
export const findUserPage = apiClient.createQueryFn(
"find_user_page",
http => async queryParams => {
const result = await http.post("/api/user/page", {
data: queryParams
});
return result.data;
}
);
This pattern appears frequently in project code:
useQuery({
queryKey: [findUserPage.key, params],
queryFn: findUserPage
});
Define Mutation Functions
export const createUser = apiClient.createMutationFn(
"create_user",
http => params => http.post("/api/user/create", {
data: params
})
);
Inside Components
import { useMutation, useQuery } from "@vef-framework-react/core";
const pageResult = useQuery({
queryKey: [findUserPage.key, searchParams],
queryFn: findUserPage
});
const createMutation = useMutation({
mutationKey: [createUser.key],
mutationFn: createUser
});
Outside Components
function fetchUserInfo() {
return apiClient.fetchQuery({
queryKey: [getUserInfo.key, { appId: "admin" }],
queryFn: getUserInfo
});
}
await apiClient.executeMutation({
mutationFn: login,
params: loginValues
});
Paginated Queries
starter.extractQueryParams() is commonly used to split query input into business parameters, pagination, and sorting:
import type { PaginatedQueryParams } from "@vef-framework-react/starter";
import { extractQueryParams } from "@vef-framework-react/starter";
export const findUserPage = apiClient.createQueryFn(
"find_user_page",
http => async (queryParams: PaginatedQueryParams<UserSearch>) => {
const { params, pagination } = extractQueryParams(queryParams);
const result = await http.post("/api/user/page", {
data: {
...params,
pagination
}
});
return result.data;
}
);
Skip Authentication for Specific Requests
import { skipAuthenticationHeader, skipAuthenticationValue } from "@vef-framework-react/core";
headers: {
[skipAuthenticationHeader]: skipAuthenticationValue
}
Suggested API File Structure
A domain API file usually contains:
- domain entity interfaces
- search parameter interfaces
- query functions exported through
createQueryFn() - mutation functions exported through
createMutationFn()
Avoid scattering raw fetch or axios calls across page code. Keeping requests under apis/* makes later integration with CrudPage, permission feedback, loading indicators, and cache reuse much cleaner.