Created
January 31, 2022 13:50
-
-
Save KATT/7b2cf31593f68f9a288afb123c42c936 to your computer and use it in GitHub Desktop.
Output data validation for tRPC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { z } from 'zod'; | |
import { TRPCError } from '@trpc/server'; | |
/** | |
* Output parser. Example use-cases: | |
* - Resolvers where you touch sensitive data that you don't wanna risk leaking | |
* - Hairy resolvers where it's hard to follow what the resolver returns | |
* @param schema Zod Schema | |
* @param output The output | |
* @returns A parsed output, guaranteed to conform to the schema | |
*/ | |
export function output<TSchema extends z.ZodTypeAny>( | |
schema: TSchema, | |
output: TSchema['_input'], | |
): TSchema['_output'] { | |
try { | |
return schema.parse(output); | |
} catch (cause) { | |
throw new TRPCError({ | |
code: 'INTERNAL_SERVER_ERROR', | |
message: 'Output validation failed', | |
cause, | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createRouter } from 'server/createRouter'; | |
import { z } from 'zod'; | |
import { TRPCError } from '@trpc/server'; | |
import { output } from 'server/lib/output'; | |
export const postRouter = createRouter() | |
.query('byId', { | |
input: z.object({ | |
id: z.string(), | |
}), | |
async resolve({ ctx, input }) { | |
const { id } = input; | |
const post = await ctx.prisma.post.findUnique({ | |
where: { id }, | |
select: { | |
id: true, | |
title: true, | |
text: true, | |
createdAt: true, | |
updatedAt: true, | |
}, | |
}); | |
if (!post) { | |
throw new TRPCError({ | |
code: 'NOT_FOUND', | |
message: `No post with id '${id}'`, | |
}); | |
} | |
// Strictly validate the output before returning the result | |
return output( | |
z.object({ | |
id: z.string(), | |
title: z.string(), | |
text: z.string(), | |
createdAt: z.date(), | |
updatedAt: z.date(), | |
}), | |
post, | |
); | |
}, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment