-
Notifications
You must be signed in to change notification settings - Fork 27
Description
It'd be really nice to be able to add a custom serializer/deserializer to workflow steps when passing data between them, especially since the type inference is currently happy with Dates and others even though it actually breaks in real life.
Example:
import { serve } from "@upstash/qstash/nextjs";
import devalue from "devalue";
import { z } from "zod";
const endpointPayloadSchema = z.object({
eventId: z.string(),
});
export const workflowEndpoint = serve<z.infer<typeof endpointPayloadSchema>>(
async (context) => {
const payload = endpointPayloadSchema.parse(context.requestPayload);
const data = await context.run(
"fetch-data",
async () => {
const event = await db.get(payload.eventId);
return { event };
},
{ serialize: devalue.stringify, deserialize: devalue.parse }
);
await context.run(
"send-email",
async () => {
await sendEmail({
templateId: 1,
templateData: {
date: Intl.DateTimeFormat("en-US", {
day: "numeric",
weekday: "long",
month: "long",
year: "numeric",
}).format(data.event.startDate),
},
});
},
{ serialize: devalue.stringify, deserialize: devalue.parse }
);
}
);Currently, this code (minus the serialize/deserialize bit) works typescript-wise, but fails in real life because event.startDate is not deserialized as a Date but as a string. I'm assuming the underlying logic is performing a JSON.stringify/JSON.parse.
This could also be added at the serve level, to ensure consistency between the steps.
I've tried doing it in userland, it works but is pretty annoying type-wise. I have not found a better way than explicitly defining all my return types and do return devalue.stringify(response as ResponseType) and then const parsedData = devalue.parse(data) as ResponseType which is difficult when the return types are complex.
One outstanding question: what does this mean for the actual qstash platform? Currently, you can see the output data on teh platform as what looks like a Go print, which sounds to me like the output is parsed by qstash and that would make the use of user-defined serialization hard to work with.