I want to validate the API response that I'm getting from a REST API using a Zod schema. For example, I have this user schema and this API
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) => ({
getPokemonByName: builder.query<user, string>({
query: (id) => `user/${id}`,
}),
}),
})
I want to validate the API response against the userSchema using Zod. However, I'm unsure whether to use the parse or safeParse function provided by Zod.
Could you please clarify where in my code should I perform the response validation, and whether I should use parse or safeParse for this scenario?
You now have responseSchema
and rawResponseSchema
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: (build) => ({
getPokemonByName: builder.query({
query: (id) => `user/${id}`,
responseSchema: userSchema,
}),
getTransformedPokemonByName: build.query({
query: (id) => `user/${id}`,
// you can infer untransformed results
rawResponseSchema: userSchema,
// then infer transformed results from here
transformResponse: (response) => ({
...response,
published_at: new Date(response.published_at),
}),
}),
}),
})
You can just use transformResponse
provided by redux toolkit query to validate the response using the userSchema. If the response doesn't match the schema, an error will be triggered.
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) => ({
getPokemonByName: builder.query<User, string>({
query: (id) => `user/${id}`,
transformResponse: (response) => {
userSchema.parse(response);
return response;
},
}),
}),
});