brillout / telefunc

Remote Functions. Instead of API.
https://telefunc.com
MIT License
688 stars 31 forks source link

zod again #105

Closed lkj4 closed 7 months ago

lkj4 commented 7 months ago

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

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 commented 7 months ago

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

lkj4 commented 7 months ago

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:

brillout commented 7 months ago

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