Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zod again #105

Closed
lkj4 opened this issue Apr 2, 2024 · 3 comments
Closed

zod again #105

lkj4 opened this issue Apr 2, 2024 · 3 comments

Comments

@lkj4
Copy link

lkj4 commented Apr 2, 2024

tl;dr ded. rt validators such as zod are important for a DRY archittecture (edit: with rt validators i mean validators which do not compile ts types to rt validators)

Not that I am big fan of zod or other rt-validators but why I think we'd still need them:

  1. First, we need to remind ourselves that the formdata we receive from an html form isn't typed; this means that if we have a generic handeSubmit function we wouldn't benefit of type-checking (just in the context of calling the RP in an generic handleSubmit)
  2. So, once we have a generic handleSubmit and we will have one (because every app has many forms submitting different shapes but using one DRY handleSubimt), we still need to find a way to differentiate all these forms; there're are many options, so I want to narrow down these with one key requirement, I want to declare as little as possible per form/api call/context; this is very important once you refactor, e.g. renaming tables which affect the entire app structure
  3. After a lot of back and forth, I found that you need only the shape of the form and you can derive everything else from it; however you need to have the shape not just as a type but as a rt entity.

Now, we can derive everything from that

  • The actual form: We can just iterate over the shape's keys and create from it the form and its input types programmatically
  • The client-side validator: Before we submit we can do a client-side validation, this is optional because we could just live with server-side validation but at the end we have a much nicer UX; and again, we have it anyway because of the prior step
  • The server-side validator: The important part here is not that we can also use it on the server-side but that if we can easily import the rt validation in both the client- and server-side without specifying the import, so when we refactor we wouldn't need to rename anything; In the best case scenario the .telefunc file would host this validator too and hence, the file itself has it and the client-side just imports the telefunc call signature from ./

This gets complex but it's actually pretty elegant, let's do an example: We want to add crud functions to a resource, we still maintain a rest-like file structure which also hosts all view files like with all modern framweworks. Let's have a recipe app and some path:

/users/me/recipes

In this folder is everything, view files, server files, etc., e.g. with SvelteKit this would bee +page.svelte, +page.server.ts, +server.ts, etc.

Let's look at two RPCs in this context: create (recipe) and update (recipte), so we could just have a create.telefunc.ts file and because its location we know it's about recipe creation. The client, in our case, +page.svelte imports the call signature just with ./create.telefunc which is great because in a case of a refactor of the table naming recipes nothing has to be changed.

But the client doesn't know the payload. Now, we could manually create the form but this doesn't help: The form is type-less anyway, so why would we need type-checking and hints for the call signature anyway (ofc there are other reasons)? So, because formdata is type-less we need rt validations or we just sent some random blob to the server without any client-side form validation.

If the client would also get some rt validators through create.telefunc it could do everything described in 1, 2 and 3 and again, in the case of a refactor, nothing had to be changed because the context (the folder) would stay the same, even if the folder names got renamed. And it is fully dry.

I think this is a huge opportunity since Telefunc is the only TS RPC solution with an elegant and simple architecture.

ps and re Zod: I don't care which rt validator is used but it should be an rt one and one which would still exist in some years

@brillout
Copy link
Owner

brillout commented Apr 5, 2024

Good point, I've bumped the priority for supporting runtime validators such as zod.

@brillout brillout closed this as not planned Won't fix, can't repro, duplicate, stale Apr 5, 2024
@lkj4
Copy link
Author

lkj4 commented Apr 7, 2024

Thanks, and just to articulate the requirements again in a more simpler way and just to get started: This isn't really about zod, I should have named the issue differently since I am really not a big fan of zod:

  • Allow to disable shield (when doing TS)
  • Allow a custom validator via a middleware
  • Bonus: Allow the client to import just the validator from the telefunc file but ofc not the the code from the server endpoint

@brillout
Copy link
Owner

Yes, that's the intention of #97. I've updated the issue's title to better reflect that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants