我使用Zod来验证包含JSON数据的HTTP请求。目前,我使用的模式如下(为了可读性,简化了(:
const z = require('zod')
const payloadSchema = z.object({ name: z.string(), age: z.number().min(18) })
const requestSchema = z.object({ payload: z.string() })
// ...
const req = requestSchema.parse(request)
const raw = JSON.parse(req.payload)
const payload = payloadSchema.parse(raw)
console.log(payload.name) // << this is what I'm interested into
Zod是否提供了一种更简单的方法来深度解析一个包含我不知道的JSON字符串的形状?
const z = require('zod')
const payloadSchema = z.object({ name: z.string(), age: z.number().min(18) })
const requestSchema = z.object({ payload: z.string().json(payloadSchema) })
// ...
const req = requestSchema.parse(request)
console.log(req.payload.name) // << this is what I'm interested into
根据Zod作者的回应,在GitHub(此处(
这里推荐的方法是使用预处理来解析有效载荷。
const z = require('zod')
const payloadSchema = z.object({ name: z.string(), age: z.number().min(18) })
const requestSchema = z.object({
payload: z.preprocess((val) => JSON.parse(val), payloadSchema),
})
const req = requestSchema.parse({payload:'{"name": "Beth", "age": 20}'})
// req.payload.name === Beth
// req.payload.age === 20
(为清晰起见,对代码进行了编辑(
我认为如果json还没有解析,那么你这样做是唯一的方法。奇怪的是,您会有一个请求模式(可能是检查从用于调用HTTP调用的库返回的请求对象(,它是一个对象,但有效负载尚未经过JSON解析。
以下是您的代码示例的runkit:https://runkit.com/robert-rendell-the/6311cbb991ef9900086d4971
当HTTP请求到达时,一些库(Nest.js(会对负载进行json解析,因此您不需要json解析步骤
我假设这就是你的请求到达时的样子:
{ payload: "{ name: '', age: 18}" }
理想情况下,您希望像Nest这样的东西来进行解析,这样您的zod模式/zod解析就可以像下面这样直接:
const z = require('zod')
const payloadSchema = z.object({ name: z.string(), age: z.number().min(18) })
const requestSchema = z.object({ payload: payloadSchema })
// ...
const req = requestSchema.parse({ payload: { name: '', age: 18}})
console.log(req.payload.name)