The web is everywhere. What is the best way to create websites and develop applications? If you google „web development“, there are millions of hits. The opinions are so many, diverse, contradicting, and overwhelming.

When I was starting out and developing my first web application, my first impression of the structure of the web was very favorable. I appreciated the built-in and enforced separation of behavior from content (HTML) and styling (CSS).

However, my understanding of how to create a web application was that the entire application needed to be rendered in JavaScript in the client of the application. The client would then send periodic updates to the server and would update the page based on the responses. This is called a single-page application and there are several frameworks like React and Angular which standardize how they are supposed to be developed.

I found front-end development frustrating. If I changed one little thing in the front end, I would have to remember to change it in the back end. The same was the case if I changed something in the back end. It was increasingly complex, increasingly difficult to remember what I had done before. Eventually, I found it so frustrating that I quit. I was only going to do back-end development from that point on.

I distinctly remember the first time I rendered an HTML form in my web application. I had defined a click handler for the button in the form, but when I clicked on it, the whole application disappeared, and frustrated with this seemingly horrifying behavior, I turned to Stack Overflow for the answer.

Pretty soon I was adding event.preventDefault(); as the first line of every click handler that I ever wrote so that my application would not have any unexpected behavior.

How a form works

I did not understand what the default behavior of an HTML form was until I participated in our internal ROCA workshop. For some people this may seem completely obvious, but it was not for me, and in my experience, I am not the only one.

It turns out that HTML is not only meant as a markup language to describe how a page is structured. It also has semantics. The most common semantic element is a link:

<a href="/example-uri">Link Text</a>

Another very powerful semantic element in HTML is a form:

<form method="get" action="/example-uri">
    <input type="text" name="param1" value="Text Field">
    <button type="submit">Click me!</button>
</form>

The default method for a form is the GET method. This means that a form with only an action and a submit button is semantically identical to a link. However, a form also makes it possible to modify the query string for the url. The above form, if it were clicked, would send the following GET request to the server: GET /example-uri?param1=Text+Field

Different input fields offer different semantics. A checkbox field

<input type="checkbox" name="food" value="Cheese">

will generate the query string ?food=Cheese only if the checkbox is selected.

If you use radio buttons in a form, the browser ensures that at maximum one of the options is selected.

<input type="radio" name="color" value="Red">
<input type="radio" name="color" value="Blue">
<input type="radio" name="color" value="Yellow">

A select element performs a similar function, but displays the values in a drop-down menu.

<select name="color">
    <option value="Red">
    <option value="Blue">
    <option value="Yellow">
</select>

When you want to send a list of elements to the server, you can just give multiple inputs the same name.

<input type="checkbox" name="order" value="Hamburger" checked>
<input type="checkbox" name="order" value="Cheese" checked>
<input type="checkbox" name="order" value="Ketchup">

This will then be translated as the query string ?order=Hamburger&order=Cheese which will be interpreted by the server as a list of values.

Forms are, therefore, a way of specifying a request to the server. Once the form is submitted, the request is sent to the server and the server handles it.

Handling Requests on the Server

The second piece of the puzzle is handling the requests on the server. A form is simply a tool for constructing an HTTP request and sending it to the web server that is serving the web application. For this reason, to understand how a form works, it is important to understand the fundamentals of HTTP.

An HTTP request consists of a method (e.g. GET) and a URI to a resource (e.g. /cat.png). An HTTP server takes this request and decides what to do with it. Then it returns an HTTP response to the user which contains a status code and content. A web browser knows both how to send an HTTP request (via link or form) and how to handle the response that comes back from the server. The most common action will be to simply render the content of the response in the browser window. It is also possible to use URL redirection to navigate within the application.

By default, an HTML form only supports the GET and POST HTTP methods. According to the HTTP 1.1 Specification, GET requests should only be used to retrieve resources, never to modify them. A POST request, however, can be used to modify existing resources.

Other HTTP methods, like PUT, DELETE, and PATCH can be very useful when creating RESTful services. Many web frameworks also provide for these HTTP methods by tunneling within a POST request:

<form method="post" ...>
    <input type="hidden" name="_method" value="put">
    ...
</form>

Even with all of this information, it might be difficult to conceptualize how such a web application could be constructed.

As an example, consider a web application for managing ebooks. By executing GET /books, you would get an HTML page listing all of the books that you have added so far. You can also render an HTML form in the page, allowing you to add a book with POST /books?title=Title&author=Author&nrStars=4. After adding the book, the application might redirect you back to the /books page where you would see the new book rendered. The page might contain links to a particular book, GET /books/:bookid, which would display more information about the book, and you could render forms in the page to allow you to update the book (PUT /books/:bookid) or remove it from your library (DELETE /books/:bookid).

Programming web pages in this way is old-fashioned. However, it is also tried and true and will work in every single browser, even if JavaScript is not available ([1],[2]). I can also say with relative certainty that it will continue working for the forseeable future.

Luckily for us, there are great web frameworks that are available to help us. Some of them include:

I still love the separation of behavior, content, and styling that is inherent in the web. However, the behavior of the web is not defined, as I once thought, using JavaScript. The behavior of a web application is defined by the web server that is serving the application. If I want to change the behavior of the application, I now only have to do it in one place.

So what do I use JavaScript for? Progressive Enhancement to improve the appearance of the website once it has been rendered. There are use cases where it is necessary to create a rich client in our web browser. If that is the case, then it might make sense to use something like React for the resource in our application that needs this. However, in the vast majority of cases, we simply don’t need it if we have a fundamental understanding of HTML forms and HTTP.

It is challenging and fun to create a website that works without JavaScript. It requires you to stretch your creative muscles. And most importantly, creating a webpage in this way will increase the platforms that your application can run on and make it more accessible for everybody to use.

  1. Everyone has JavaScript, right?  ↩

  2. Why Availability Matters  ↩