Skip to content

API Client自动生成

我们使用react-query调用后端的Rest API.

后端API是通过swagger自动生成的。当后端API更新时,我们可以重新生成API Client:

bash
pnpm api:gen

自动生成工具的配置文件是kubb.config.ts.

API的定义是通过kubb.config.ts中的input.path设置的。默认是dev环境的服务器地址:

ts
  input: {
    // path: '../shared/swagger/documentation-1.0.0.json',
    path: 'https://woxapi.ent-dev.xiaokubangong.com/docs-json',
    // path: 'http://localhost:8000/docs-json',
  },

可以改成本地的swagger文件. 这个文件在每次server更新API时会自动更新。

生成的API函数在 src/api 目录。我们可以直接使用生成的hooks。

如果要修改服务器地址,例如,使用本地服务器开发,需要修改kubb.config.ts:

json
  input: {
    path: 'http://localhost:8000/docs-json', // 本地服务器(文件)
    // path: 'https://woxapi.ent-dev.xiaokubangong.com/docs-json', // 集成服务器
  },

同时,修改.env (前端调用后端服务器的地址)

bash
# backend server url
# VITE_BACKEND_URL='http://localhost:8000' // 本地服务器
VITE_BACKEND_URL='https://woxapi.ent-dev.xiaokubangong.com' // 集成服务器

使用API Client

查询(Query)

直接使用API Client生成的hooks: useXXX:

tsx
import { useLocationFindMany } from '@/api'
import React from 'react'

const DesksPage: React.FC = () => {
  const { data, error, isLoading } = useLocationFindMany({})

  if (error) {
    return <p>Error: ${error.message}</p>
  }

  return (
    <p className="read-the-docs">
      {isLoading ? (
        <div>Loading…</div>
      ) : (
        <ul>Result: {JSON.stringify(data?.result)}</ul>
      )}
    </p>
  )
}

export default DesksPage
  1. 如果加载组件时不需要自动调起API,使用enabled: false picture 6

更改(Mutation)

使用mutate hooks:

ts
const { mutate: createWebhook, isPending } = useWebhookControllerCreateOne({
  mutation: {
    onSuccess: () => {
      form.resetFields()
      modal.hide()
    },
  },
})

const { mutate: updateWebhook } = useWebhookControllerUpdateOne({
  mutation: {
    onSuccess: () => {
      form.resetFields()
      modal.hide()
    },
  },
})

更改后的数据会自动invalidate query cache。所以你不需要做什么页面就会自动更新。

如果有时候不需要自动更新,需要关闭回调后的invalidation, 可传入:

ts
const { mutate: createWebhook, isPending } = useWebhookControllerCreateOne({
  invalidationOnSuccess: false,
  mutation: {
    ...
  },
})

手动invalidate,使用useInvalidate:

tsx
const TaskList: React.FC = () => {
  const invalidateTasks = useInvalidate('tasks')
  setTimeout(() => {
    invalidateTasks()
  }, 3000)
}

useInvalidate的实现方式:

ts
const useInvalidate = (queryKeyPart: string | string[]) => {
  const queryClient = useQueryClient()

  const invalidate = () => {
    queryClient.invalidateQueries({
      queryKey: [
        'api',
        'v5',
        ...(Array.isArray(queryKeyPart) ? queryKeyPart : [queryKeyPart]),
      ],
    })
  }

  return invalidate
}

用户侧和管理侧

用户侧和管理侧的API是分开的。用户侧的前端必须使用用户侧API,管理侧的前端必须使用管理侧API。名字上带useAdmin...的是管理侧API。不带Admin的是用户侧API。

例如,同样是获取分店列表,用户侧使用useLocationFindMany, 而管理侧使用useAdminLocationFindMany.

使用原则:

  1. 前端提供了isUserClient, isAdminClient函数用于判断当前页面是管理端还是用户端
  2. 公有组件,例如选择分店弹框,需要根据isUserClient判断,例如
tsx
const { data: locations } = isUserClient() ? useLocationFindMany() : useAdminLocationFindMany()
  1. 其他组件,一般根据目录结构,在user目录下的使用用户侧API,admin目录下的使用管理侧API