> [!info] see more
> [Hono is now AI ready - Yusuke Wada](https://blog.yusu.ke/hono-ai-ready/)
Let's create a super simple blog. Expect and then validate input from users as follows:
```ts
const schema = z.object({
title: z.string().min(1),
content: z.string().min(1),
})
```
You can use `.openapi()` in this Zod OpenAPI (This function is based on [**Zod to OpenAPI**](https://github.com/asteasolutions/zod-to-openapi), thanks a lot!).
```ts
const schema = z.object({
title: z.string().min(1).openapi({ example: 'About today' }),
content: z.string().min(1).openapi({ example: 'Today is a good day...' }),
})
```
Use this and define the path, content type, and response information as a route:
```ts
export const routeAddPost = createRoute({
method: 'post',
path: '/posts',
request: {
body: {
content: {
'application/json': {
schema: schema,
},
},
},
},
responses: {
'200': {
description: 'OK',
content: {
'application/json': {
schema: z.object({
ok: z.boolean(),
}),
},
},
},
},
})
```
That's everything "_OpenAPI-like_". Now it's time to implement the logic as usual. Here we are using [Cloudflare D1](https://developers.cloudflare.com/d1/) as our database.
```ts
app.openapi(routeAddPost, async (c) => {
const { title, content } = c.req.valid('json')
const id = crypto.randomUUID()
await c.env.DB.prepare('INSERT INTO posts(id, title, content) values (?, ?, ?)')
.bind(id, title, content)
.run()
return c.jsonT({
ok: true,
})
})
```
The great thing about this Zod OpenAPI is that it is terribly Type-Safe. If the request's Content-Type is `application/json`, it will suggest the 1st arg of `c.req.valid()` as `json` and expect the response to be `ok:boolean` as defined in the response schema.

The API spec is generated as JSON and you can view the documentation in the Swagger UI.
