You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在RTK Query中用Zod Schema验证API响应:位置与函数选择

用Zod验证RTK Query的API响应

验证该放在哪?

RTK Query的builder.query里有个transformResponse钩子,这就是处理API响应、做验证最合适的地方——数据存入Redux前就能完成校验,不会把脏数据塞到状态里。

parse还是safeParse?

  • parse:如果API返回的数据不符合Schema,直接抛错,触发RTK Query的错误状态(比如isError)。适合你确定API格式严格靠谱,或者希望不合规数据直接报错的场景。
  • safeParse:不会抛错,返回一个带success字段的对象。适合需要自定义错误处理的情况,比如打个日志、返回默认值,不让整个请求失败。

代码示例

用parse的写法

import { z } from 'zod';
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const userSchema = z.object({
  id: z.string(),
  name: z.string(),
  age: z.number(),
});

type User = z.infer<typeof userSchema>;

export const userAPI = createApi({
  reducerPath: 'userAPI',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://some-api/' }),
  endpoints: (builder) => ({
    getUserById: builder.query<User, string>({ // 注意这里是大写的User,原代码小写写错了
      query: (id) => `user/${id}`,
      transformResponse: (response: unknown) => {
        // 直接用parse验证,不合规就抛错
        return userSchema.parse(response);
      },
    }),
  }),
});

用safeParse的写法

import { z } from 'zod';
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const userSchema = z.object({
  id: z.string(),
  name: z.string(),
  age: z.number(),
});

type User = z.infer<typeof userSchema>;

export const userAPI = createApi({
  reducerPath: 'userAPI',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://some-api/' }),
  endpoints: (builder) => ({
    getUserById: builder.query<User | null, string>({ // 类型加个null,处理验证失败的情况
      query: (id) => `user/${id}`,
      transformResponse: (response: unknown) => {
        const validationResult = userSchema.safeParse(response);
        if (validationResult.success) {
          return validationResult.data;
        } else {
          // 自定义处理:打日志、返回null或者默认用户对象
          console.error('用户数据验证失败:', validationResult.error);
          return null;
        }
      },
    }),
  }),
});

小提醒

  • 原代码里的builder.query<user, string>是笔误,要改成User(对应你定义的类型)。
  • 如果是获取多个用户,直接用userSchema.array()来验证整个响应数组就行。

内容的提问来源于stack exchange,提问作者Tanmay Bindal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:47:43