Typing an RPC client #428
-
We're currently trying out zod as a way of validating a very large RPC service. Our types are currently working but they have grown very complicated making the it hard to sell to other teams that don't necessarily hold a black belt in TypeScript. Our current implementation is as follows: import * as z from 'zod';
const rpcMethods = {
dog: {
params: z.object({
name: z.string(),
age: z.number(),
}),
result: z.object({
happiness: z.number(),
treats: z.array(z.string()),
}),
},
cat: {
params: z.object({
sleepy: z.boolean(),
}),
result: z.object({
miceCaught: z.number(),
}),
},
};
export function createJSONRPCRequest<
TMethod extends keyof typeof rpcMethods,
TSchema extends typeof rpcMethods[TMethod]
>(method: TMethod, params: z.infer<TSchema['params']>): Request {
rpcMethods[method].params.parse(params);
return new Request('/json-rpc', {
method: 'POST',
body: JSON.stringify({
method,
params,
}),
});
}
export function parseJSONRPCResponse<
TMethod extends keyof typeof rpcMethods,
TSchema extends typeof rpcMethods[TMethod]
>(method: TMethod, data: unknown): z.infer<TSchema['result']> {
return rpcMethods[method].result.parse(data);
}
export async function fetchJSONRPC<
TMethod extends keyof typeof rpcMethods,
TSchema extends typeof rpcMethods[TMethod]
>(
method: TMethod,
params: z.infer<TSchema['params']>
): Promise<z.infer<TSchema['result']>> {
const request = createJSONRPCRequest(method, params);
const response = await fetch(request);
if (!response.ok) {
throw new Error(response.statusText);
}
const data = await response.json();
const result = rpcMethods[method].result.parse(data);
return result;
} Firstly I was wondering if I've missed a Zod feature that would allow us to simplify the above types and secondly if there's a way of reducing the computational overhead when the above |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
I'm not sure what Zod could do to simplify either of those things. Do you have any specific suggestions? For a fully typed, hand-rolled RPC client I think this is pretty concise. |
Beta Was this translation helpful? Give feedback.
I'm not sure what Zod could do to simplify either of those things. Do you have any specific suggestions? For a fully typed, hand-rolled RPC client I think this is pretty concise.