May 6, 2021

Building a library II - Planning phase

So we have a great candidate for a library. It’s a problem that occurs in most of our projects, it’s well defined, it’s limited in scope and we have a great understanding of the domain. Let’s make a plan.

For this exercise web forms are a good example. They are very common, well defined, limited in scope and a lot of people have at least a basic understanding of them, and so should work great as an example.

Define it

A web form has a minimum of the following parts

  • Fields

  • Order of fields

  • Visual representation

In addition, with the web, you will want to deal with

  • i18n (internationalization)

  • validation

There are more things that can be added, but they become more optional, while i18n and validation sort of are mandatory. Let’s break down what we have so far a bit more.

Field

For each field we have an element, which is a visual representation of the field. An element will need additional attributes, such as CSS classes, style, attributes, etc.

Each field also holds data. This data will need to be initialized.

Each field will also need to handle events. When a user does something with the element, we want something to happen. These events are always tied up with the element.

Order of fields

The order of the fields is concerned with in which order we visually show them for users. This order is not necessarily the order in which the fields are defined for the form. In addition the order could be changeable, and the order could also be split up.

Visual representation

Given a set of fields for a form, how they are shown could be implemented in any number of ways, including simple stuff like tables, lists, paragraphs, divs, etc and more advanced ways such as wizards.

i18n

Once we have a form, it would be really great to be able to use it in any kind of language. For this we need the form to support i18n.

validation

Lastly, for anything that is user input related, we need to validate that the data that has been put in, is accurate. This is both for security concerns, but also a UX thing, where we want to be helpful to the user and tell them when something is not correct.

This means we need to have validation on the data, both on the frontend (what is visually shown) and the backend (validate that the data won’t breach our application).

In additation, if something goes wrong, we need to show that to the user, so that he/she can fix the error (say a faulty date input). When the input has been fixed, the error message needs to go away. Of course, the error message must also support i18n.

We can also get validation from outside the logic of the form. This means we need the ability to tell the form that something wrong has happened.

We can have multiple validations per field, meaning possibly multiple error messages.

Finally, we can have validation logic that is spread out over multiple fields.

Scope

The scope is somewhat limited in that we can define the fields and the ordering as a logical unit. i18n is an external dependancy, while validation is mostly internal, but can be dependant on external factors (such as login credentials for example).

What we ideally want is a single definition of a form, that holds all the logic of the form as well as all of the visual representation. The more declarative we can make the form, the more resuability we can get out of it as well. Forms are a bit tricky, in that they potentially involve a lot of I/O. In addition, separating the visual representation from the internal logic/validation of the fields which only care about the data can also be tricky.

If we also can make the form malleable in the form of overrides, we would get something very flexible, that could be re-used basically everywhere.

Understanding the domain

The web as a domain is a bit quirky. From 1993 it has gone from a simple document viewer with a brilliant publishing schema, to what we have today, where multiple layers upon layers have been added in order to make it into something that’s a bit of a Frankenstein monster. Very useful; not the most elegant of solutions.

The first thing to note is that HTML is sticky. It’s hard to move the HTML away from the internal logic completely. Not impossible, but easy to make mistakes. We have to be on our guard here.

Validation needs a bridge to the visual layer of the form, where error messages, supported by i18n, can be fed into the visual layer, without the visual layer having any idea about the validation part.

Frontend vs backend is also an important factor when building a library such as this. Building it primarily for the backend will make some things easier, such as validation, but also limit ourselves to a request/response cycle of the early web (not necessarily a bad thing). If we want something for a fancy frontend, where HTML generation happens via javascript, we run into problems of needed to validate in two places, while gaining a useful UX boon with the user getting immidate feedback, instead of having to do a roundtrip for any feedback.

Great…​ now what?

So, we have a greater understanding of what we want to build. The next step is to dive into the thought process that went into ez-wire, the library I wrote based off of ez-form, which in turn is based off of Django forms.

Tags: programming