[{"data":1,"prerenderedAt":596},["ShallowReactive",2],{"page:\u002Fextensions\u002Fkubb-labs\u002Fplugin-client\u002Fguides\u002Fvalidate-requests-and-responses":3},{"id":4,"title":5,"body":6,"description":582,"extension":585,"frontmatter":586,"heading":5,"meta":587,"navigation":588,"order":589,"path":590,"seo":591,"sitemap":592,"source":4,"stem":593,"__hash__":594,"hasPopups":595},"extensions\u002Fextensions\u002Fkubb-labs\u002Fplugin-client\u002Fguides\u002Fvalidate-requests-and-responses.md","Validate requests and responses",{"type":7,"value":8,"toc":581},"minimark",[9,21,180,183,232,256,548,566],[10,11,12,16,17,20],"p",{},[13,14,15],"code",{},"@kubb\u002Fplugin-client"," does not validate on its own. With ",[13,18,19],{},"validator"," set, it passes the schemas to your client, which runs them.",[22,23,24],"code-group",{},[25,26,31],"pre",{"language":27,"filename":28,"code":29,"class":30},"typescript","kubb.config.ts","import { defineConfig } from 'kubb\u002Fconfig'\nimport { pluginTs } from '@kubb\u002Fplugin-ts'\nimport { pluginZod } from '@kubb\u002Fplugin-zod'\nimport { pluginClient } from '@kubb\u002Fplugin-client'\n\nexport default defineConfig({\n  input: '.\u002FpetStore.yaml',\n  output: { path: '.\u002Fsrc\u002Fgen' },\n  plugins: [\n    pluginTs(),\n    pluginZod(),\n    pluginClient({ importPath: '..\u002F..\u002F..\u002Fclient', validator: 'zod' }),\n  ],\n})","shiki shiki-themes github-light github-dark dark:github-dark",[13,32,34,54,55,54,67,54,79,54,91,54,93,54,108,54,119,54,130,54,135,54,143,54,150,54,170,54,175],{"class":33},"language-typescript",[35,36,39,43,47,50],"span",{"class":37,"style":38},"line","display: inline",[35,40,42],{"style":41},"color:#D73A49;--shiki-dark:#F97583","import",[35,44,46],{"style":45},"color:#24292E;--shiki-dark:#E1E4E8"," { defineConfig } ",[35,48,49],{"style":41},"from",[35,51,53],{"style":52},"color:#032F62;--shiki-dark:#9ECBFF"," 'kubb\u002Fconfig'","\n",[35,56,57,59,62,64],{"class":37,"style":38},[35,58,42],{"style":41},[35,60,61],{"style":45}," { pluginTs } ",[35,63,49],{"style":41},[35,65,66],{"style":52}," '@kubb\u002Fplugin-ts'",[35,68,69,71,74,76],{"class":37,"style":38},[35,70,42],{"style":41},[35,72,73],{"style":45}," { pluginZod } ",[35,75,49],{"style":41},[35,77,78],{"style":52}," '@kubb\u002Fplugin-zod'",[35,80,81,83,86,88],{"class":37,"style":38},[35,82,42],{"style":41},[35,84,85],{"style":45}," { pluginClient } ",[35,87,49],{"style":41},[35,89,90],{"style":52}," '@kubb\u002Fplugin-client'",[35,92],{"class":37,"style":38},[35,94,95,98,101,105],{"class":37,"style":38},[35,96,97],{"style":41},"export",[35,99,100],{"style":41}," default",[35,102,104],{"style":103},"color:#6F42C1;--shiki-dark:#B392F0"," defineConfig",[35,106,107],{"style":45},"({",[35,109,110,113,116],{"class":37,"style":38},[35,111,112],{"style":45},"  input: ",[35,114,115],{"style":52},"'.\u002FpetStore.yaml'",[35,117,118],{"style":45},",",[35,120,121,124,127],{"class":37,"style":38},[35,122,123],{"style":45},"  output: { path: ",[35,125,126],{"style":52},"'.\u002Fsrc\u002Fgen'",[35,128,129],{"style":45}," },",[35,131,132],{"class":37,"style":38},[35,133,134],{"style":45},"  plugins: [",[35,136,137,140],{"class":37,"style":38},[35,138,139],{"style":103},"    pluginTs",[35,141,142],{"style":45},"(),",[35,144,145,148],{"class":37,"style":38},[35,146,147],{"style":103},"    pluginZod",[35,149,142],{"style":45},[35,151,152,155,158,161,164,167],{"class":37,"style":38},[35,153,154],{"style":103},"    pluginClient",[35,156,157],{"style":45},"({ importPath: ",[35,159,160],{"style":52},"'..\u002F..\u002F..\u002Fclient'",[35,162,163],{"style":45},", validator: ",[35,165,166],{"style":52},"'zod'",[35,168,169],{"style":45}," }),",[35,171,172],{"class":37,"style":38},[35,173,174],{"style":45},"  ],",[35,176,177],{"class":37,"style":38},[35,178,179],{"style":45},"})",[10,181,182],{},"Each generated call now includes the schemas:",[25,184,186],{"language":27,"code":185,"class":30},"request({\n  method: 'POST',\n  url: '\u002Fpet',\n  validator: { response: addPetResponseSchema, error: addPetErrorSchema },\n  ...config,\n})",[13,187,188,54,195,54,205,54,215,54,220,54,228],{"class":33},[35,189,190,193],{"class":37,"style":38},[35,191,192],{"style":103},"request",[35,194,107],{"style":45},[35,196,197,200,203],{"class":37,"style":38},[35,198,199],{"style":45},"  method: ",[35,201,202],{"style":52},"'POST'",[35,204,118],{"style":45},[35,206,207,210,213],{"class":37,"style":38},[35,208,209],{"style":45},"  url: ",[35,211,212],{"style":52},"'\u002Fpet'",[35,214,118],{"style":45},[35,216,217],{"class":37,"style":38},[35,218,219],{"style":45},"  validator: { response: addPetResponseSchema, error: addPetErrorSchema },",[35,221,222,225],{"class":37,"style":38},[35,223,224],{"style":41},"  ...",[35,226,227],{"style":45},"config,",[35,229,230],{"class":37,"style":38},[35,231,179],{"style":45},[10,233,234,235,237,238,241,242,245,246,251,252,255],{},"Add a ",[13,236,19],{}," field to your ",[13,239,240],{},"RequestConfig",", then run the schemas in ",[13,243,244],{},"client",". Zod schemas follow ",[247,248,250],"a",{"href":249},"https:\u002F\u002Fstandardschema.dev","Standard Schema",", so ",[13,253,254],{},"~standard.validate"," works with any compatible library:",[25,257,260],{"language":27,"filename":258,"code":259,"class":30},"src\u002Fclient.ts","type Result = { value: unknown; issues?: undefined } | { issues: ReadonlyArray\u003Cunknown> }\ntype Schema = { '~standard': { validate: (value: unknown) => Result | Promise\u003CResult> } }\n\nexport type RequestConfig = {\n  \u002F\u002F ...\n  validator?: { request?: Schema; response?: Schema; error?: Schema }\n}\n\n\u002F\u002F inside client(), after reading the body\nconst result = await config.validator?.response?.['~standard'].validate(body)\nif (result && 'issues' in result && result.issues) throw new Error('Response validation failed')\nconst validatedBody = result && 'value' in result ? result.value : body",[13,261,262,54,323,54,377,54,379,54,394,54,400,54,436,54,441,54,443,54,448,54,474,54,517],{"class":33},[35,263,264,267,270,273,276,280,283,287,290,293,296,299,302,305,307,309,311,314,317,320],{"class":37,"style":38},[35,265,266],{"style":41},"type",[35,268,269],{"style":103}," Result",[35,271,272],{"style":41}," =",[35,274,275],{"style":45}," { ",[35,277,279],{"style":278},"color:#E36209;--shiki-dark:#FFAB70","value",[35,281,282],{"style":41},":",[35,284,286],{"style":285},"color:#005CC5;--shiki-dark:#79B8FF"," unknown",[35,288,289],{"style":45},"; ",[35,291,292],{"style":278},"issues",[35,294,295],{"style":41},"?:",[35,297,298],{"style":285}," undefined",[35,300,301],{"style":45}," } ",[35,303,304],{"style":41},"|",[35,306,275],{"style":45},[35,308,292],{"style":278},[35,310,282],{"style":41},[35,312,313],{"style":103}," ReadonlyArray",[35,315,316],{"style":45},"\u003C",[35,318,319],{"style":285},"unknown",[35,321,322],{"style":45},"> }",[35,324,325,327,330,332,334,337,339,341,344,346,349,351,353,355,358,361,363,366,369,371,374],{"class":37,"style":38},[35,326,266],{"style":41},[35,328,329],{"style":103}," Schema",[35,331,272],{"style":41},[35,333,275],{"style":45},[35,335,336],{"style":52},"'~standard'",[35,338,282],{"style":41},[35,340,275],{"style":45},[35,342,343],{"style":103},"validate",[35,345,282],{"style":41},[35,347,348],{"style":45}," (",[35,350,279],{"style":278},[35,352,282],{"style":41},[35,354,286],{"style":285},[35,356,357],{"style":45},") ",[35,359,360],{"style":41},"=>",[35,362,269],{"style":103},[35,364,365],{"style":41}," |",[35,367,368],{"style":103}," Promise",[35,370,316],{"style":45},[35,372,373],{"style":103},"Result",[35,375,376],{"style":45},"> } }",[35,378],{"class":37,"style":38},[35,380,381,383,386,389,391],{"class":37,"style":38},[35,382,97],{"style":41},[35,384,385],{"style":41}," type",[35,387,388],{"style":103}," RequestConfig",[35,390,272],{"style":41},[35,392,393],{"style":45}," {",[35,395,396],{"class":37,"style":38},[35,397,399],{"style":398},"color:#6A737D;--shiki-dark:#6A737D","  \u002F\u002F ...",[35,401,402,405,407,409,411,413,415,417,420,422,424,426,429,431,433],{"class":37,"style":38},[35,403,404],{"style":278},"  validator",[35,406,295],{"style":41},[35,408,275],{"style":45},[35,410,192],{"style":278},[35,412,295],{"style":41},[35,414,329],{"style":103},[35,416,289],{"style":45},[35,418,419],{"style":278},"response",[35,421,295],{"style":41},[35,423,329],{"style":103},[35,425,289],{"style":45},[35,427,428],{"style":278},"error",[35,430,295],{"style":41},[35,432,329],{"style":103},[35,434,435],{"style":45}," }",[35,437,438],{"class":37,"style":38},[35,439,440],{"style":45},"}",[35,442],{"class":37,"style":38},[35,444,445],{"class":37,"style":38},[35,446,447],{"style":398},"\u002F\u002F inside client(), after reading the body",[35,449,450,453,456,458,461,464,466,469,471],{"class":37,"style":38},[35,451,452],{"style":41},"const",[35,454,455],{"style":285}," result",[35,457,272],{"style":41},[35,459,460],{"style":41}," await",[35,462,463],{"style":45}," config.validator?.response?.[",[35,465,336],{"style":52},[35,467,468],{"style":45},"].",[35,470,343],{"style":103},[35,472,473],{"style":45},"(body)",[35,475,476,479,482,485,488,491,494,496,499,502,505,508,511,514],{"class":37,"style":38},[35,477,478],{"style":41},"if",[35,480,481],{"style":45}," (result ",[35,483,484],{"style":41},"&&",[35,486,487],{"style":52}," 'issues'",[35,489,490],{"style":41}," in",[35,492,493],{"style":45}," result ",[35,495,484],{"style":41},[35,497,498],{"style":45}," result.issues) ",[35,500,501],{"style":41},"throw",[35,503,504],{"style":41}," new",[35,506,507],{"style":103}," Error",[35,509,510],{"style":45},"(",[35,512,513],{"style":52},"'Response validation failed'",[35,515,516],{"style":45},")",[35,518,519,521,524,526,528,530,533,535,537,540,543,545],{"class":37,"style":38},[35,520,452],{"style":41},[35,522,523],{"style":285}," validatedBody",[35,525,272],{"style":41},[35,527,493],{"style":45},[35,529,484],{"style":41},[35,531,532],{"style":52}," 'value'",[35,534,490],{"style":41},[35,536,493],{"style":45},[35,538,539],{"style":41},"?",[35,541,542],{"style":45}," result.value ",[35,544,282],{"style":41},[35,546,547],{"style":45}," body",[10,549,550,551,554,555,558,559,561,562,565],{},"Return ",[13,552,553],{},"validatedBody"," as ",[13,556,557],{},"data",", so a schema that transforms the value takes effect. Without a response schema, ",[13,560,553],{}," is the original ",[13,563,564],{},"body",".",[10,567,568,569,572,573,576,577,580],{},"Set ",[13,570,571],{},"validator: { request: 'zod' }"," or ",[13,574,575],{},"{ response: 'zod' }"," to pass one direction only. Without ",[13,578,579],{},"pluginZod()"," in the plugins list, generation stops with an error.",{"title":582,"searchDepth":583,"depth":583,"links":584},"",5,[],"md",{},{},true,null,"\u002Fextensions\u002Fkubb-labs\u002Fplugin-client\u002Fguides\u002Fvalidate-requests-and-responses",{"title":5},{"loc":590},"extensions\u002Fkubb-labs\u002Fplugin-client\u002Fguides\u002Fvalidate-requests-and-responses","MIBX5lnNRyiQMvZ2MKRibjdPzNWLpYtVQRU3gA15kEE",false,1792704354431]