数据验证器
在 QwikCity 中,数据验证器对于验证请求事件和动作、加载器的数据是必不可少的。这些验证在执行相关的动作或加载器之前在服务器端进行。与 zod$()
函数类似,Qwik 提供了一个专用的 validator$()
函数来实现这个目的。
import {
type RequestEvent,
type RequestEventAction,
routeAction$,
validator$,
} from "@builder.io/qwik-city";
export const useAction = routeAction$(
async (data, requestEvent: RequestEventAction) => {
return { foo: "bar" };
},
validator$(async (ev: RequestEvent, data) => {
if (ev.query.get("secret") === "123") {
return { success: true };
}
return {
success: false,
error: {
message: "secret is not correct",
},
};
}),
);
当向 routeAction()
提交请求时,请求事件和数据会根据定义的验证器进行验证。如果验证失败,动作将在 routeAction.value
属性中放置验证错误。
export default component$(() => {
const action = useAction();
// 在提交之前,动作的值是 undefined
if (action.value) {
if (action.value.failed) {
// 如果查询字符串没有 secret,则动作失败
action.value satisfies { failed: true; message: string };
} else {
action.value satisfies { searchResult: string };
}
}
return (
<button onClick$={() => action.submit({ search: "foo" })}>提交</button>
);
});
多个验证器
动作和加载器可以有多个验证器,它们按照相反的顺序执行。在下面的示例中,验证器的执行顺序是 validator3
-> validator2
-> validator1
。
const validator1 = validator$(/*...*/)
const validator2 = validator$(/*...*/)
const validator3 = validator$(/*...*/)
export const useAction = routeAction$(
async (data, requestEvent: RequestEventAction) => {
return { foo: "bar" };
},
validator1,
validator2,
validator3, // 将首先执行
);
如果 validator3
在其成功返回对象中有一个 data
属性,这个数据将传递给下一个验证器 validator2
。如果你不想覆盖原始提交的数据,请避免将 data
属性放在成功返回对象中。
export const useAction = routeAction$(
async (data, requestEvent: RequestEventAction) => {
console.log(data); // { message: "hi, I am validator1" }
return { foo: "bar" };
},
// validator1
validator$((ev, data) => {
console.log(data); // { message: "hi, I am validator2" }
return {
success: true,
data: {
message: "hi, I am validator1",
},
};
}),
// validator2
validator$((ev, data) => {
console.log(data); // { message: "hi, I am validator3" }
return {
success: true,
data: {
message: "hi, I am validator2",
},
};
}),
// validator3
validator$((ev, data) => {
console.log(data); // 您提交的数据
return {
success: true,
data: {
message: "hi, I am validator3",
},
};
}),
);
返回对象
数据验证器在其返回对象中期望特定的属性。
验证成功
对于成功的验证,success
属性必须为 true。
interface Success {
success: true;
data?: any;
}
验证失败
interface Fail {
success: false;
error: Record<string, any>;
status?: number;
}
当验证器返回一个失败的对象时,它的行为类似于在动作或加载器中使用 fail()
方法。
const status = 500;
const errorObject = { message: "123" };
export const useAction = routeAction$(
async (_, { fail }) => {
return fail(status, errorObject);
},
validator$(async () => {
return {
success: false,
status,
errorObject,
};
}),
);
validator$()
和 zod$()
在动作中同时使用 对于动作来说,类型化的数据验证器 zod$()
应该是 routeAction$
的第二个参数,后面是其他的数据验证器 validator$()
。
export const useAction = routeAction$(
async (data, requestEvent: RequestEventAction) => {
return { foo: "bar" };
},
zod$(/*...*/),
validator$(/*...*/),
validator$(/*...*/),
);