-
Hi! This is truly an amazing library thanks so much for building it! I've been trying to figure out how to get the raw request body in a handler. I'm currently using conform (https://github.com/edmundhung/conform) to manage my form state in Next.js. Previously I was using export const contactAction = os
.input(zfd.formData({}))
.output(
z.object({
result: z.custom<SubmissionResult<string[]>>(),
}),
)
.handler(async ({ input, }) => {
const submission = parseWithZod(input, {}); // 👈 I'd like to be able to pass in the raw request's form data here.
return {};
})
.actionable({}); In actionClient.inputSchema(zfd.formData({})).stateAction<{
conform: SubmissionResult<string[]>;
}>(async ({ clientInput }) => {
/**
* clientInput isFormData | FormDataLikeInput | { [x: string]: unknown; }
*/
const submission = parseWithZod(clientInput as FormData, {
schema: createLoginSchema(),
});
/// ....
return {
conform: submission.reply(),
};
}); I looked at https://orpc.unnoq.com/docs/server-action#parseformdata-and-getissuemessage-utilities, but this as I gather would parse my form FormData into JSON and send that to an actionable handler. Thanks! 🙏 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Hi @lazakrisz! I'm Dosu and I’m helping the orpc team. orpc doesn't have a built-in Here's a minimal example using the Fetch adapter that injects the raw import { RPCHandler } from '@orpc/server/fetch'
const OVERRIDE_BODY_CONTEXT = Symbol('OVERRIDE_BODY_CONTEXT')
interface OverrideBodyContext {
fetchRequest: Request
}
const handler = new RPCHandler(router, {
adapterInterceptors: [
(options) => options.next({
...options,
context: {
...options.context,
[OVERRIDE_BODY_CONTEXT as any]: {
fetchRequest: options.request,
},
},
}),
],
rootInterceptors: [
(options) => {
const { fetchRequest } = (options.context as any)[OVERRIDE_BODY_CONTEXT] as OverrideBodyContext
return options.next({
...options,
request: {
...options.request,
async body() {
const contentType = fetchRequest.headers.get('content-type')
if (contentType?.startsWith('multipart/form-data')) {
return fetchRequest.formData()
}
// fallback to default body parser
return options.request.body()
},
},
})
},
],
}) In your handler, you can then access the raw For Next.js, remember to add: export const config = {
api: {
bodyParser: false,
},
} References: This approach gives you full control over how the raw body is handled and passed to your handler, similar to what you had with trpc's To reply, just mention @dosu. How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other |
Beta Was this translation helpful? Give feedback.
-
If you pass export const getting = pub
.input(z.instanceof(FormData))
.handler(async ({ input }) => {
console.log({ input })
// return `Hello ${input.name}!`
})
.actionable() In other word, the input is whatever you pass when calling (make sure nextjs support transfer it) |
Beta Was this translation helpful? Give feedback.
If you pass
FormData
as input when calling server action, the input will be form-dataIn other word, the input is whatever you pass when calling (make sure nextjs support transfer it)