is it worth it to have meaningful errors returned from server side form validation?

like is it worth it at that point to return an error for every field that is invalid from the backend or should you just throw a bad request assuming you already have full validation on client side like if someone does somehow bypass client validation lets say by disabling javascript is it even worth it to have meaningful server errors for every field i can see the argument for progressive enhancement but like if you want to have good ux on forms it feels like you almost always need javascript
63 Replies
Josh
Josh2y ago
so the way i generally handle this, is to do validation on the backend, but just return a 400 to the client, and let your JS do the actual form validation now, if your trying to make a standalone API that you want people to use, maybe you could argue it would be nice for people trying to use your api to see whats going wrong, but generally youll just be sending 400's
stoyko
stoyko2y ago
Imo, if you expect the whole form to be submitted at once and don't have some form of partial updates/a complex form that is separated in multiple parts, I don't think there is a reason to validate every single field tbh. You validate the whole form, if something doesn't validate throw a generic Bad Response with some generic message. And if you have some fields that have additional logic attached to them, you can validate those separately and if they fail, throw a more specific Bad Request. That is how we handle most of our form validation via the BE
Josh
Josh2y ago
If specific fields need specific inputs, like say you need to input a product code in a specific format or something, then ill usually do per-field validation just for a nice UX, but this is always better solved with some sort of form library instead of trying to do it yourself
cucaracha
cucarachaOP2y ago
i agree with these points. is disabling javascript all that common? trying to see this from the progressive enhancement side
Josh
Josh2y ago
if your using react and they disable javascript your site wont work anyways iirc assuming your using react well, the client components wont render
stoyko
stoyko2y ago
This isn't just about "disabling JS though". Is your API public? Is it gonna be consumed from other clients as well? Or is it something that is only used by your app. Because that makes a major difference in how you approach all of this. Yeah, that is what I meant. If you have some specific logic tied to a field, you validate for that specific field additionally.
Josh
Josh2y ago
that and per field validation for hey this field is required and you left it blank
stoyko
stoyko2y ago
Ah, fair. Yeah, we use GQL at work and I haven't build a non-GQL API for a while. Thus I didn't consider validating required fields
Josh
Josh2y ago
disabling js is very common for webscrapers and some headless browsers (cli browsers), but if someone is visiting your site like that they probably arent going to the forms anyways im in a weird spot with one of my contracts where the client kinda knew python and specifically wanted me to build our backend in python with a standalone react frontend so the stack is a complete mess. Needless to say i dont have the fancy tools like gql but now we are at 16k loc and he gave up trying to understand it so im trying to slowly convert parts of it to next / literally anything other than python
stoyko
stoyko2y ago
Uhhhh, are there no gql libs for Python? That sucks honestly Yeah, if it's such a small project, you can easily convert it to something like TRPC even, if you don't need the separate BE
Josh
Josh2y ago
oh shit there is although tbh i dont think gql would be very helpful for most of my shit
stoyko
stoyko2y ago
Yeah, tbf gql isn't the easiest to implement properly
Josh
Josh2y ago
most of our app is very large chains of complex ish logic with tons of side effects
stoyko
stoyko2y ago
And you can easily fuck yourself over
Josh
Josh2y ago
right im pretty comfy with where its at now, i just wish pythons type system was actually good
stoyko
stoyko2y ago
You mean it actually existed. Cuz just becuase there is a lib about it, doen't mean it's there. deranged
Josh
Josh2y ago
poohheh
Tom
Tom2y ago
ill just throw this out there: i think there ar e2 kinds of errors theres errors like 'your first name shouldnt have a number in it' that can be caught with validation on the client side but then there are errors that are like 'you cant create an account if you already have one' where only the server can really validate it personally i think zod + trpc is one of the best parts of the t3 stack because it gives me a way to send both kind of errors. my client can then figure out how to put those errors in relevant spots but IMO the validation should always be done by the server anyway cause otherwise you could end up with garbage in your db (either from unknowing api users or malicious actors)
cucaracha
cucarachaOP2y ago
how do you guys choose to validation on client side? onChange of every field or onSubmit? i really dont know what most users prefer
Josh
Josh2y ago
deff not onchange. use a form lib of some sort, they usually have good error handlers built in
Josh
Josh2y ago
Performant, flexible and extensible forms with easy-to-use validation.
cucaracha
cucarachaOP2y ago
thinking of using react-hook-form rn wondering why you prefer onsubmit over onchange?
Josh
Josh2y ago
i dont think ive used it yet, but ive heard very, very good things ab it if you use onChange, then the user will always see an error either at the beginning of the form, OR while they are typing
cucaracha
cucarachaOP2y ago
i prefer onsubmit as well. with good labels and information to guide the user into putting correct info. but just wanna see other perspectives
Josh
Josh2y ago
onSubmit will only show errors when the user has actually tried to submit something errorful yepp
cucaracha
cucarachaOP2y ago
agreed
Josh
Josh2y ago
to do really good error management youll find you need a rediculous amount of state management just ot make it look nice aka, use react-hook-form
cucaracha
cucarachaOP2y ago
yea. most of the time overkill. but yea i agree
Tom
Tom2y ago
i use rhf + zod, but IMO rhf is like.... really good for really basic forms i dont have a better alternative but my app has a lot of pretty dynamic forms and rhf basically acts as its own store you have to communicate with cause it does everything with uncontrolled inputs that said. the fact that it uses uncontrolled inputs makes the performance wayyyyyy better
cucaracha
cucarachaOP2y ago
is that a problem when you have inputs that are dependent on eachother?
Tom
Tom2y ago
wdym?
cucaracha
cucarachaOP2y ago
just started using rhf so im not sure if its even related but im thinking of validation where one input might be dependent on another
Tom
Tom2y ago
you can do validation like that thru zod with refine / superRefine my problems are more like 'you picked x so i need to get that value, do some transforms on it and display y'
cucaracha
cucarachaOP2y ago
ahhh okay i see. are the docs a good enough learning resource? i usually look for vids but not sure if theres any up to date ones
Tom
Tom2y ago
i dont mind the zod docs. i havent needed to look anywhere else for that the rhf ones are a lot more meh
cucaracha
cucarachaOP2y ago
mb i mean the rhf ones. zod ones are pretty decent
Tom
Tom2y ago
i think the rhf docs are ok. its just when you get into some of the nitty gritty the biggest things ive struggled with are: 1) you can have optional values in your zod validator, but none of the rhf functions can take undefined as a value this is further made confusing because defaultValues are all defined as DeepPartial<YourValidatorType> so your default values can all be undefined 2) it doesnt solve some of the basic stuff around like things like making a textbox only allow number inputs you still gotta deal with the raw html props for that 3) since it maages its own state you sometimes have to do werid things with watch(), or useEffect() to sync the state of what is rendered in your form with the state of the form itself there are escape hatches for a lot of things, but i have a hard time wrapping things in nice patterns ive also hit some of the real edge cases of it cause my app has a few very large, very dynamic forms
cucaracha
cucarachaOP2y ago
def gonna keep an eye out for this. interesting
Tom
Tom2y ago
with a lot of logic
cucaracha
cucarachaOP2y ago
do you prefer to handle errors on submit or onchange?
Tom
Tom2y ago
the default with rhf is pretty good. the errors dont show up until you submit the form, then everything is onchange cause people hate to be told theyre wrong while theyre still in the middle of typing for some of the heavier forms that need to do heavy logic when some of the fields change i use the onBlur option instead bt thats purely because of performance
cucaracha
cucarachaOP2y ago
for your large forms, do you split them into multi part forms? multi part forms are usually a better ux im thinking?
Tom
Tom2y ago
i opted for tabs. the thing is my forms are really big, but theres defaults for most of it so its very customizable, but if you want you can just click submit and it will work
cucaracha
cucarachaOP2y ago
interesting. i guess thats like a multi part form but without "steps"?
Tom
Tom2y ago
yeah if you want you can try it https://truefinals.com/create youll need to make an account tho (i reccomend signing in with google cause i do have actual email verification and stuff)
cucaracha
cucarachaOP2y ago
that looks pretty dope. is that MUI?
Tom
Tom2y ago
some mui components for the inputs and buttons and icons. layout is all just tailwind
cucaracha
cucarachaOP2y ago
very sleek look. def gonna take a peek inside
Tom
Tom2y ago
ty still wip
cucaracha
cucarachaOP2y ago
does your forms persist with network loss / refresh?
Tom
Tom2y ago
not refresh. network loss is fine
cucaracha
cucarachaOP2y ago
wondering if rhf supports that with like localstorage or whatever
Tom
Tom2y ago
it might
cucaracha
cucarachaOP2y ago
is this prod ready? do you have mau?
Tom
Tom2y ago
kinda. im using it with some beta users hoping to start marketting it sometime this summer
cucaracha
cucarachaOP2y ago
hardest fukin part lol. marketing.
Tom
Tom2y ago
yeah well ill find out
cucaracha
cucarachaOP2y ago
yup. its a learning process. definitely the most important part of any app
Tom
Tom2y ago
yeah well hopefully i can find some people to do that for me
cucaracha
cucarachaOP2y ago
definitely going to hit you up later this summer if you dont mind. would love to see if you have any learnings from that stage whenever you get to it. its what i struggle with most
Tom
Tom2y ago
yeah well ill also say like.... im probably not a great example on that front basically i found 1 enterprise customer before i even started working on this so like no matter what as long as i land that 1 user the app will be worth it and i already have (although im still working thru contract negotiations) but theyre already using it
cucaracha
cucarachaOP2y ago
yea thats fair enough. everything else is extra for you
Tom
Tom2y ago
yeah
Want results from more Discord servers?
Add your server