In the previous articles mostly I was focusing on Go. In this article I would take a step back and talk about another critical piece of a web application, the protocol that is used to transfer data between clients and server. Until this time we only used the HTTP protocol. Now let's talk about other options that are available and the advantages that they bring.
HTTP is a very good protocol and it is lasted a long time but it does have one downfall that is making it less and less attractive as the primary transport layer in modern web applications. So if we look at a web application from a high level, we got a client and we got a server and they send messages back and forth. But if we take a look at a login message it looks something like this:
If we go to a given path then when we make a request through the protocol, we gonna have headers and body passed from the client to the server. Now in HTTP this is transfered as plain text. So this means if we are not talking directly to the server we want (if there are some servers between) those servers can easily understand this information too. Now obviously this presents a tremendous security vulnerability and is not recommended to use in any application.
Now with HTTPS what we gonna do is change the transport layer a little bit. So instead of writing directly on a TCP connection we will add another layer called TLS (transport layer security).
So we are going to modify the data that is being sent to that it's encrypted by both the client and the server, and only our client and our server going to accept that information. Still the servers between will se that data, but they will not understand what it means. This time if we send our data as plain text through this TLS, the servers between will see this data as garbage thanks by encrypting.
Now for communication in Go there are two functions to use. http.ListenAndServe() and http.ListenAndServeTLS()
http.ListenAndServe() is perfect for HTTP requests. http.ListenAndServeTLS() works the same however it provides that TLS for us.
We start with a TCP connection. When we send a request from the client to the server it will go with a header and a body in the request. Now there can be cases when the body is too large and it is separated into multiple package but in general we are going to send a header and a body together. So we have monolithic requests and responses.
Now the problem that we have here is that the header can not be compressed in any way because that header describes all of the contents of the request to the response. So for example we got a context-type in the header, we got authorization information, we got our length etc. This leads to inefficiently if the header becomes large in size, especially if we talk about hundreds or thousands of requests at the time. So in HTTP/2 there is a fundamental shift in how the TCP connections are used.
We are going to still build on the top of a TCP connection but in this one connection we are going to establish what are called streams. Streams are independent communcation pipelines within the TCP connection so they dont interact with another, but they allow multiple messages to be send back and forth between the same connection. Now in these streams we gonna send informations what are called frames.
So instead of those monolithic header body combinations we are breaking the information into individual frames and those frames can be optimised independently. These frames will be the header (information about the resource we are requesting). The server can send some headers back, and then if its got too many to fit in the header frame it can send what are called continuation frames in oder to pact more information to send down to the client. It might send some data then, then headers and continuation frames So by splitting the request and response up into these individual frames each data type can be optimised individually both on client and server.
There is another thing that HTTP/2 gives us is something called server push.
In order to see what server push is going to do for us, let's demonstrate what happens usually when you visit a website .
The client makes a get request on the /home route. The server is going to see it, process that, and response with the index.html back to the client. The client is going to parse it and it will see that it requires a stylesheet file, so its gonna make another request for the stylesheet to the server and the server sends it back. Now this means that we use requests to the server that is not necessary. We know at design time, that resource will be necessary, so we can take advantage of it, and this is where server push comes in.
So when a request comes in the /home route, you immediately send the stylesheet file and then the index.html file. The client will accept this file, however it does not know yet why. So when the client will start to parse that file , it will see that it needs a stylesheet and it is already available for it.