Mayhul
Mayhulβ€’2w ago

Migrating to use Superjson

I currently have a tRPC router that is being used by a web app & React native client. My current version does not use superjson. I want to start using superjson as my transformer. Is there an easy way for me to make this migration? When I tried just starting to use Superjson, our React native client started running into errors because the old mobile client was not using superjson but the server was. I wish I could access context in my transformer so I could choose to only do the transformation for new clients. Any other ideas on how I can make the switch-over while maintaining backwards compatibility for older clients?
7 Replies
Alex / KATT 🐱
I don't know a painless way of doing it as it can't be conditionally enabled/disabled maybe you just need to spin up endpoints for the old clients that doesn't use superjson or force update all clients
Mayhul
MayhulOPβ€’2w ago
If I'm merging multiple routers together, is there a way for me to apply the superjson transformer to just 1 router?
Alex / KATT 🐱
no
Nick
Nickβ€’2w ago
Honestly sounds like a situation to have a load balancer which checks the app version via headers/useragent and a second deployment without the transformer in place
Mayhul
MayhulOPβ€’3d ago
Here's the solution I came up with: Step 1, update my code to look like:
//On client
export const trpcClient = trpc.createClient({
transformer: {
serialize: (data: any) => {
return superjson.serialize(data);
},
deserialize: (data: any) => {
const isSuperJson = data.json !== undefined;
if (isSuperJson) {
return superjson.deserialize(data);
} else {
return data;
}
},
},
});

//On server
const t = initTRPC.context<Context>().create({
transformer: {
serialize: (data: any) => {
return data;
},
deserialize: (data: any) => {
const isSuperJson = data.json !== undefined;
if (isSuperJson) {
return superjson.deserialize(data);
} else {
return data;
}
},
},
});
//On client
export const trpcClient = trpc.createClient({
transformer: {
serialize: (data: any) => {
return superjson.serialize(data);
},
deserialize: (data: any) => {
const isSuperJson = data.json !== undefined;
if (isSuperJson) {
return superjson.deserialize(data);
} else {
return data;
}
},
},
});

//On server
const t = initTRPC.context<Context>().create({
transformer: {
serialize: (data: any) => {
return data;
},
deserialize: (data: any) => {
const isSuperJson = data.json !== undefined;
if (isSuperJson) {
return superjson.deserialize(data);
} else {
return data;
}
},
},
});
Deploy this, force all of our React Native to update. Then, once all of our clients have updated, I can switch to using superjson as normal. Basically wrapping superjson to be backwards compatible. Assuming that we don't use json as a key in any of our trpc inputs/ouputs, are there any other issues that you think this could cause?
Alex / KATT 🐱
hmmm this could work
Nick
Nickβ€’2d ago
That’s really smart and simple, nice job

Did you find this page helpful?