Open Studio
Recipes

Validate every API response

Point a Fetch client at the generated Zod schemas to validate every response body at runtime.

Generate the Zod schemas, then point a client at them. Setting the Fetch client's validator to 'zod' runs every response body through the matching schema at runtime. The option also accepts an object form to validate request bodies too.

kubb.config.ts
typescript
import { defineConfig } from 'kubb/config'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginZod } from '@kubb/plugin-zod'
import { pluginFetch } from '@kubb/plugin-fetch'

export default defineConfig({
  input: './petStore.yaml',
  output: { path: './src/gen', clean: true },
  plugins: [
    pluginTs({ output: { path: 'types', mode: 'directory' } }),
    pluginZod({ output: { path: 'zod', mode: 'directory' } }),
    pluginFetch({
      output: { path: 'clients', mode: 'directory' },
      validator: 'zod',
    }),
  ],
})

Output example ​

src/gen/clients/findPetsByStatus.ts
typescript
import type { Options, RequestResult } from '../.kubb/client'
import type { FindPetsByStatusOptions, FindPetsByStatusResponses } from '../types/FindPetsByStatus'
import { client } from '../.kubb/client'
import { findPetsByStatusResponseSchema, findPetsByStatusErrorSchema } from '../zod/findPetsByStatusSchema'

export function findPetsByStatus<ThrowOnError extends boolean = true>(options: Options<FindPetsByStatusOptions, ThrowOnError> = {}): Promise<RequestResult<FindPetsByStatusResponses, ThrowOnError>> {
  const { client: request = client, ...config } = options

  return request({ method: 'GET', url: '/pet/findByStatus', validator: { response: findPetsByStatusResponseSchema, error: findPetsByStatusErrorSchema }, ...config }) as Promise<RequestResult<FindPetsByStatusResponses, ThrowOnError>>
}
usage.ts
typescript
import { findPetsByStatus } from './src/gen/clients/findPetsByStatus'

// throws if the response body fails findPetsByStatusResponseSchema.parse(...)
const { data } = await findPetsByStatus({ query: { status: ['available'] } })