[{"data":1,"prerenderedAt":756},["ShallowReactive",2],{"page:\u002Fextensions\u002Fkubb-labs\u002Fplugin-fetch\u002Fguides\u002Fserialization":3},{"id":4,"frontmatter":5,"title":6,"heading":6,"body":7,"path":755,"source":4},"extensions\u002Fkubb-labs\u002Fplugin-fetch\u002Fguides\u002Fserialization.md",{},"Configure serialization",{"type":8,"value":9,"toc":746},"minimark",[10,23,28,37,52,197,203,207,236,243,258,273,377,381,401,410,520,526,554,617,627,637,641,652,691,701,736],[11,12,13,14,18,19,22],"p",{},"The generated client encodes parameters using OpenAPI ",[15,16,17],"code",{},"style"," and ",[15,20,21],{},"explode",", serializes request bodies by content type, and decodes responses by media type. Each generated operation carries its parameter styles and content types, so most requests need no extra setup.",[24,25,27],"h2",{"id":26},"override-parameter-serialization","Override parameter serialization",[11,29,30,31,36],{},"Check the ",[32,33,35],"a",{"href":34},"https:\u002F\u002Fkubb.dev\u002Fdocs\u002F5.x\u002Freference\u002Fserialization#parameter-styles","default parameter styles and encoding"," before replacing a serializer.",[11,38,39,40,43,44,47,48,51],{},"Override ",[15,41,42],{},"serializer.query",", ",[15,45,46],{},".body",", or ",[15,49,50],{},".path"," on the client. Omitted functions retain their defaults:",[53,54,58],"pre",{"language":55,"code":56,"class":57},"typescript","import { client } from '.\u002Fgen\u002F.kubb\u002Fclient'\nimport qs from 'qs'\n\nclient.setConfig({\n  serializer: {\n    query: (params) => qs.stringify(params, { arrayFormat: 'brackets' }),\n  },\n})","highlights",[15,59,61,88,89,88,101,88,103,88,118,88,132,88,184,88,193],{"class":60},"language-typescript",[62,63,66,70,74,78,81,84],"span",{"class":64,"style":65},"line","display: inline",[62,67,69],{"style":68},"color:#d73a49;--hls-dark:#f97583","import ",[62,71,73],{"style":72},"color:#005cc5;--hls-dark:#79b8ff","{ ",[62,75,77],{"style":76},"color:#24292e;--hls-dark:#e1e4e8","client ",[62,79,80],{"style":72},"} ",[62,82,83],{"style":68},"from ",[62,85,87],{"style":86},"color:#032f62;--hls-dark:#9ecbff","'.\u002Fgen\u002F.kubb\u002Fclient'","\n",[62,90,91,93,96,98],{"class":64,"style":65},[62,92,69],{"style":68},[62,94,95],{"style":76},"qs ",[62,97,83],{"style":68},[62,99,100],{"style":86},"'qs'",[62,102],{"class":64,"style":65},[62,104,105,108,111,115],{"class":64,"style":65},[62,106,107],{"style":76},"client",[62,109,110],{"style":68},".",[62,112,114],{"style":113},"color:#6f42c1;--hls-dark:#b392f0","setConfig",[62,116,117],{"style":72},"({",[62,119,120,123,126,129],{"class":64,"style":65},[62,121,122],{"style":72},"  ",[62,124,125],{"style":72},"serializer",[62,127,128],{"style":68},": ",[62,130,131],{"style":72},"{",[62,133,134,137,140,142,145,148,151,154,157,159,162,164,166,168,170,173,175,178,181],{"class":64,"style":65},[62,135,136],{"style":72},"    ",[62,138,139],{"style":72},"query",[62,141,128],{"style":68},[62,143,144],{"style":72},"(",[62,146,147],{"style":76},"params",[62,149,150],{"style":72},") ",[62,152,153],{"style":68},"=> ",[62,155,156],{"style":76},"qs",[62,158,110],{"style":68},[62,160,161],{"style":113},"stringify",[62,163,144],{"style":72},[62,165,147],{"style":76},[62,167,43],{"style":68},[62,169,73],{"style":72},[62,171,172],{"style":72},"arrayFormat",[62,174,128],{"style":68},[62,176,177],{"style":86},"'brackets' ",[62,179,180],{"style":72},"})",[62,182,183],{"style":68},",",[62,185,186,188,191],{"class":64,"style":65},[62,187,122],{"style":68},[62,189,190],{"style":72},"}",[62,192,183],{"style":68},[62,194,195],{"class":64,"style":65},[62,196,180],{"style":72},[11,198,199,200,202],{},"A serializer set this way runs for every call, but you can pass ",[15,201,125],{}," on a single call to\noverride only that request.",[24,204,206],{"id":205},"encode-request-bodies","Encode request bodies",[11,208,209,210,213,214,217,218,213,221,224,225,43,227,43,229,43,232,235],{},"The request content type decides how the body is encoded. The default serializer handles the\ncommon types: a plain object becomes JSON, ",[15,211,212],{},"multipart\u002Fform-data"," becomes ",[15,215,216],{},"FormData",", and\n",[15,219,220],{},"application\u002Fx-www-form-urlencoded",[15,222,223],{},"URLSearchParams",". Binary and already-encoded bodies\n(",[15,226,216],{},[15,228,223],{},[15,230,231],{},"Blob",[15,233,234],{},"ArrayBuffer",", typed arrays, and strings) pass through\nuntouched.",[11,237,238,239,242],{},"When an operation declares a single request content type, Kubb sets it on the generated function,\nso you pass only the body. For an operation that accepts more than one, set ",[15,240,241],{},"contentType"," on the\ncall.",[244,245,247,248,250,251,254,255,257],"blockquote",{"as":246},"note","When the body is ",[15,249,216],{},", the runtime removes any ",[15,252,253],{},"Content-Type"," header so the transport sets\nit with the multipart boundary. You do not need to set ",[15,256,212],{}," yourself, and a\nvalue you set is dropped for that request.",[11,259,260,261,264,265,268,269,272],{},"To encode a content type the default serializer does not handle, register a codec for that media\ntype. ",[15,262,263],{},"codecs"," is keyed by content type. Each entry takes a ",[15,266,267],{},"serialize"," for the request body, a\n",[15,270,271],{},"deserialize"," for the response, or both:",[53,274,276],{"language":55,"code":275,"class":57},"import { client } from '.\u002Fgen\u002F.kubb\u002Fclient'\nimport { stringify } from 'yaml'\n\nclient.setConfig({\n  codecs: {\n    'application\u002Fyaml': { serialize: (body) => stringify(body) },\n  },\n})",[15,277,278,88,292,88,308,88,310,88,320,88,330,88,365,88,373],{"class":60},[62,279,280,282,284,286,288,290],{"class":64,"style":65},[62,281,69],{"style":68},[62,283,73],{"style":72},[62,285,77],{"style":76},[62,287,80],{"style":72},[62,289,83],{"style":68},[62,291,87],{"style":86},[62,293,294,296,298,301,303,305],{"class":64,"style":65},[62,295,69],{"style":68},[62,297,73],{"style":72},[62,299,300],{"style":76},"stringify ",[62,302,80],{"style":72},[62,304,83],{"style":68},[62,306,307],{"style":86},"'yaml'",[62,309],{"class":64,"style":65},[62,311,312,314,316,318],{"class":64,"style":65},[62,313,107],{"style":76},[62,315,110],{"style":68},[62,317,114],{"style":113},[62,319,117],{"style":72},[62,321,322,324,326,328],{"class":64,"style":65},[62,323,122],{"style":72},[62,325,263],{"style":72},[62,327,128],{"style":68},[62,329,131],{"style":72},[62,331,332,334,337,339,341,343,345,347,350,352,354,356,358,360,363],{"class":64,"style":65},[62,333,136],{"style":72},[62,335,336],{"style":86},"'application\u002Fyaml'",[62,338,128],{"style":68},[62,340,73],{"style":72},[62,342,267],{"style":72},[62,344,128],{"style":68},[62,346,144],{"style":72},[62,348,349],{"style":76},"body",[62,351,150],{"style":72},[62,353,153],{"style":68},[62,355,161],{"style":113},[62,357,144],{"style":72},[62,359,349],{"style":76},[62,361,362],{"style":72},") }",[62,364,183],{"style":68},[62,366,367,369,371],{"class":64,"style":65},[62,368,122],{"style":68},[62,370,190],{"style":72},[62,372,183],{"style":68},[62,374,375],{"class":64,"style":65},[62,376,180],{"style":72},[24,378,380],{"id":379},"decode-responses","Decode responses",[11,382,383,384,386,387,389,390,392,393,396,397,400],{},"The runtime reads the response ",[15,385,253],{}," and decodes the body by it: JSON is parsed, text\nstays a string, and a binary type becomes a ",[15,388,231],{},". The negotiated media type is on the result as\n",[15,391,241],{},", so a ",[15,394,395],{},"switch (result.contentType)"," narrows ",[15,398,399],{},"data"," for an operation that returns\nmore than one.",[11,402,403,404,406,407,409],{},"To decode a media type the runtime does not handle, register a codec's ",[15,405,271],{}," for it.\n",[15,408,271],{}," receives the raw body and the content type and returns the parsed value. It runs\nbefore validation, so the schema checks the parsed value:",[53,411,413],{"language":55,"code":412,"class":57},"import { client } from '.\u002Fgen\u002F.kubb\u002Fclient'\n\nclient.setConfig({\n  codecs: {\n    'application\u002Fxml': { deserialize: (raw) => new DOMParser().parseFromString(raw as string, 'application\u002Fxml') },\n  },\n})",[15,414,415,88,429,88,431,88,441,88,451,88,508,88,516],{"class":60},[62,416,417,419,421,423,425,427],{"class":64,"style":65},[62,418,69],{"style":68},[62,420,73],{"style":72},[62,422,77],{"style":76},[62,424,80],{"style":72},[62,426,83],{"style":68},[62,428,87],{"style":86},[62,430],{"class":64,"style":65},[62,432,433,435,437,439],{"class":64,"style":65},[62,434,107],{"style":76},[62,436,110],{"style":68},[62,438,114],{"style":113},[62,440,117],{"style":72},[62,442,443,445,447,449],{"class":64,"style":65},[62,444,122],{"style":72},[62,446,263],{"style":72},[62,448,128],{"style":68},[62,450,131],{"style":72},[62,452,453,455,458,460,462,464,466,468,471,473,475,478,481,484,486,489,491,494,497,500,502,504,506],{"class":64,"style":65},[62,454,136],{"style":72},[62,456,457],{"style":86},"'application\u002Fxml'",[62,459,128],{"style":68},[62,461,73],{"style":72},[62,463,271],{"style":72},[62,465,128],{"style":68},[62,467,144],{"style":72},[62,469,470],{"style":76},"raw",[62,472,150],{"style":72},[62,474,153],{"style":68},[62,476,477],{"style":68},"new ",[62,479,480],{"style":113},"DOMParser",[62,482,483],{"style":72},"()",[62,485,110],{"style":68},[62,487,488],{"style":113},"parseFromString",[62,490,144],{"style":72},[62,492,493],{"style":76},"raw ",[62,495,496],{"style":68},"as ",[62,498,499],{"style":76},"string",[62,501,43],{"style":68},[62,503,457],{"style":86},[62,505,362],{"style":72},[62,507,183],{"style":68},[62,509,510,512,514],{"class":64,"style":65},[62,511,122],{"style":68},[62,513,190],{"style":72},[62,515,183],{"style":68},[62,517,518],{"class":64,"style":65},[62,519,180],{"style":72},[11,521,522,523,525],{},"Like the other config, ",[15,524,263],{}," can also be passed on a single call, and a per-call entry merges\nover the client one for that content type.",[11,527,528,529,531,532,535,536,43,539,542,543,43,546,549,550,553],{},"When the runtime picks the wrong parse mode because a response omits its ",[15,530,253],{}," or sets a\nmisleading one, force the mode with ",[15,533,534],{},"responseType"," on the call. It accepts ",[15,537,538],{},"'json'",[15,540,541],{},"'text'",",\n",[15,544,545],{},"'blob'",[15,547,548],{},"'arraybuffer'",", and ",[15,551,552],{},"'document'",":",[53,555,557],{"language":55,"code":556,"class":57},"const { data } = await downloadInvoice({ path: { id: '123' }, responseType: 'blob' })\n\u002F\u002F data is a Blob even when the server leaves Content-Type unset",[15,558,559,88,611],{"class":60},[62,560,561,564,566,569,571,574,577,580,583,586,588,590,593,595,598,600,602,604,606,609],{"class":64,"style":65},[62,562,563],{"style":68},"const ",[62,565,73],{"style":72},[62,567,568],{"style":76},"data ",[62,570,80],{"style":72},[62,572,573],{"style":68},"= ",[62,575,576],{"style":68},"await ",[62,578,579],{"style":113},"downloadInvoice",[62,581,582],{"style":72},"({ ",[62,584,585],{"style":72},"path",[62,587,128],{"style":68},[62,589,73],{"style":72},[62,591,592],{"style":72},"id",[62,594,128],{"style":68},[62,596,597],{"style":86},"'123' ",[62,599,190],{"style":72},[62,601,43],{"style":68},[62,603,534],{"style":72},[62,605,128],{"style":68},[62,607,608],{"style":86},"'blob' ",[62,610,180],{"style":72},[62,612,613],{"class":64,"style":65},[62,614,616],{"style":615},"color:#6a737d;--hls-dark:#6a737d","\u002F\u002F data is a Blob even when the server leaves Content-Type unset",[11,618,619,623,624,110],{},[32,620,622],{"href":621},"https:\u002F\u002Fkubb.dev\u002Fextensions\u002Fkubb-labs\u002Fplugin-fetch\u002Fguides\u002Fserver-sent-events","Server-sent events"," covers ",[15,625,626],{},"responseType: 'stream'",[11,628,629,630,18,632,634,635,110],{},"For bidirectional formats, supply both ",[15,631,267],{},[15,633,271],{}," in the media type codec, then set the operation's request and response ",[15,636,241],{},[24,638,640],{"id":639},"validate-responses","Validate responses",[11,642,643,644,647,648,651],{},"Enable ",[15,645,646],{},"validator"," on the client plugin and register ",[15,649,650],{},"pluginZod"," in the same configuration. Validation is disabled by default.",[53,653,655],{"language":55,"code":654,"class":57},"import { pluginFetch } from '@kubb\u002Fplugin-fetch'\n\npluginFetch({ validator: 'zod' })",[15,656,657,88,673,88,675],{"class":60},[62,658,659,661,663,666,668,670],{"class":64,"style":65},[62,660,69],{"style":68},[62,662,73],{"style":72},[62,664,665],{"style":76},"pluginFetch ",[62,667,80],{"style":72},[62,669,83],{"style":68},[62,671,672],{"style":86},"'@kubb\u002Fplugin-fetch'",[62,674],{"class":64,"style":65},[62,676,677,680,682,684,686,689],{"class":64,"style":65},[62,678,679],{"style":113},"pluginFetch",[62,681,582],{"style":72},[62,683,646],{"style":72},[62,685,128],{"style":68},[62,687,688],{"style":86},"'zod' ",[62,690,180],{"style":72},[11,692,693,696,697,700],{},[15,694,695],{},"'zod'"," validates the success response body, and the error body when a non-2xx call does not\nthrow. Use the object form to opt in per direction, where ",[15,698,699],{},"request"," validates the request\nbody before the call goes out:",[53,702,704],{"language":55,"code":703,"class":57},"pluginFetch({ validator: { request: 'zod', response: 'zod' } })",[15,705,706],{"class":60},[62,707,708,710,712,714,716,718,720,722,724,726,729,731,733],{"class":64,"style":65},[62,709,679],{"style":113},[62,711,582],{"style":72},[62,713,646],{"style":72},[62,715,128],{"style":68},[62,717,73],{"style":72},[62,719,699],{"style":72},[62,721,128],{"style":68},[62,723,695],{"style":86},[62,725,43],{"style":68},[62,727,728],{"style":72},"response",[62,730,128],{"style":68},[62,732,688],{"style":86},[62,734,735],{"style":72},"} })",[11,737,738,739,742,743,110],{},"With a validator set, Kubb passes the matching schema to each generated call, and the runtime\nparses the body through it. A body that does not match throws a ",[15,740,741],{},"ParseError"," with the schema's\n",[15,744,745],{},"issues",{"title":747,"searchDepth":748,"depth":748,"links":749},"",5,[750,752,753,754],{"id":26,"depth":751,"text":27},2,{"id":205,"depth":751,"text":206},{"id":379,"depth":751,"text":380},{"id":639,"depth":751,"text":640},"\u002Fextensions\u002Fkubb-labs\u002Fplugin-fetch\u002Fguides\u002Fserialization",1793747914968]