Client with Zod
Combine Zod validation with HTTP clients
Use Zod schemas alongside your SWR or TanStack Query client for runtime validation.
Configuration
Generate both the HTTP client and Zod schemas:
import { defineConfig } from 'orval';
export default defineConfig({
// HTTP client generation
petstore: {
input: {
target: './petstore.yaml',
},
output: {
mode: 'tags-split',
client: 'swr',
target: 'src/api/endpoints',
schemas: 'src/api/models',
mock: true,
},
},
// Zod schema generation
petstoreZod: {
input: {
target: './petstore.yaml',
},
output: {
mode: 'tags-split',
client: 'zod',
target: 'src/api/endpoints',
fileExtension: '.zod.ts',
},
},
});Use fileExtension: '.zod.ts' to avoid filename conflicts with the HTTP client files.
Generated Files
src/api/
├── endpoints/
│ └── pets/
│ ├── pets.ts # SWR hooks
│ ├── pets.msw.ts # MSW mocks
│ ├── pets.faker.ts # Faker mocks
│ └── pets.zod.ts # Zod schemas
└── models/
└── ...Usage
import { useListPets, useCreatePets } from './api/endpoints/pets/pets';
import { CreatePetsBodyItem } from './api/endpoints/pets/pets.zod';
function App() {
const { data } = useListPets();
const { trigger } = useCreatePets();
const createPet = async () => {
const pet = { name: 'Buddy', tag: 'dog' };
try {
// Validate before sending
const validatedPet = CreatePetsBodyItem.parse(pet);
await trigger([validatedPet]);
} catch (error) {
if (error instanceof ZodError) {
console.error('Validation failed:', error.errors);
}
}
};
return (
<div>
<button onClick={createPet}>Create Pet</button>
{data?.map((pet) => (
<div key={pet.id}>{pet.name}</div>
))}
</div>
);
}Full Example
See the complete SWR with Zod example on GitHub.