Form Validations

Ben

When my front end is decoupled from my backend via JSON API, how does my front end know what kind of validation logic my backend does on the data I provide it? Usually, it doesn't! How do I communicate what is a valid input to my user?

I won't lie, typically I just recreate the validation logic in both places. It isn't very DRY, and it's a pain to change. My backend is even in Javascript, so you'd think it'd be easier to share logic! But the server and browser are different places, so how do I communcate that a date picker can only be from yesterday to next month? In current form, the front end would "know" the requirement and the html produced would be:

<input type="date" min="2024-02-14" max="2024-03-15" name="reservation-date">

Then the backend would have some validation logic that checked that requirement again. A naive example would look like:

reservationDate > "2024-02-14" && reservationDate < "2024-03-15"

If the requirement changed to now allow 2 months into the future, which would you change first? I would relax the backend validation to the new requirement, then the front end. 2 changes in 2 codebases with 2 different deployments. This case is simple too, since the change is simple. But I still can't relax the front end requirement first, the backend would complain even though it looks like a date I can choose.

Server Driven Architecture

What if I could encode all the requirements and validations into a response, sent by the server, that my front end could generate the right control, with all the right validations baked in? Relaxing the allowable date from 1 month to 2 months would only requirea change to my backend, no change to my front end. What does that look like in practice? If I'm using a JSON API, I might have this shape:

{
  controls: [{
    type: "date",
    min: "2024-02-14",
    max: "2024-03-15",
    name: "reservation-date"
  }]
}

But notice how similar that is to the input above?

<input type="date" min="2024-02-14" max="2024-03-15" name="reservation-date">

I've basically encoded all the input attributes in json! Why not save myself a step and just send the input element itself? In a web application using React, with a decoupled JSON API, sending HTML is hard and unintuitive. But if you're already serving HTML from your backend, this should be a breeze (and likely what you're already doing). And templating language will suffice, I like Nunjucks with Express

More complicated validations

What about when the allowable date is dynamic, maybe based on the type of reservation?

<input type="radio" name="reservation-type" value="one">
<input type="radio" name="reservation-type" value="two">
<input type="radio" name="reservation-type" value="three"

Now you front end has logic to change the date picker min/max values based on the state of the "reservation-type" checkbox. How do you code that in a Server Driven Architecture? My only answer is I don't know; and it's too complicated for me to think of an answer that will satisfy all permutations of the equation. So in my day job, react app, I encode the difference validations two places: react in the front end and the mutation in the backend. But in a server driven architecture, we could have an endpoint to receive the date picker and call it every time the value of reservation-type changed. If we could send html, we would just have three date pickers on the backend we could send. This is a case for HTMX; I can reuse the validation logic from my backend and any updates can all be performed in once place, the backend. I can send and receive and splice html with ease. Or if there were another serialization format my front end could understand, maybe I could use that.