Drop a file into server/resources, export defineResource(), and Hydro wires the routes, validation and documentation at runtime.
- schema
Describe the shapeZod validates request bodies and feeds the generated OpenAPI document.
- provider
Read from anywhereImplement list/get against memory, SQL, KV, an external API, or your own repository layer.
- processor
Own the writesCreate, update and delete receive already-parsed input plus params, auth and request metadata.
- extras
Add capabilitiesFilters, relationships, auth rules and custom operations layer onto the same resource definition.
import { defineResource } from '#hydro'import { z } from 'zod'export default defineResource({ name: 'Book', path: 'books', schema: z.object({ id: z.string().optional(), title: z.string().min(1).max(200), authorId: z.string().optional(), available: z.boolean().default(true), }), filters: ['title', 'authorId'], provider: { async list(ctx) { const { offset, itemsPerPage } = ctx.query.pagination return { items: books.slice(offset, offset + itemsPerPage), total: books.length, } }, async get(ctx) { return books.find(book => book.id === ctx.params.id) ?? null }, }, processor: { async create(ctx) { const book = { ...ctx.input, id: crypto.randomUUID() } books.push(book) return book }, async update(ctx) { return updateBook(ctx.params.id, ctx.input) }, async delete(ctx) { await deleteBook(ctx.params.id) }, },})