All about Request — Response cycle and how Go works with it.

Archit Joshi
5 min readMay 31, 2019

Before diving into the core let us understand a simple yet powerful concept which serves as a solid foundation of the whole Internet, that is client/server model.

What is Client/Server architecture ?

Client/Server model is a computing model in which the server hosts, delivers and manages most of the resources and services to be consumed by the client. This type of architecture has one or more client computers connected to a central server over a network or internet connection.

Hmm..? Interesting, but how do they understand each other. For example requester speaks Chinese and respond-er servers in English, Hence there is a need of common protocol (some set of rules) which each have to understand to communicate efficiently.
Which in the case of Internet communications is HTTP.

What is a HTTP Request ?

Whenever we want to access some files (be it HTML files of a website) on the internet we type in the URL which is nothing but the address of the file we want in the Browser. The browser then generates a sophisticated request header. Let us analyze a sample request –

GET /requested_URL HTTP/1.1
Host: abs.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/json,application/xml;
Accept-Language: en-US,en;
Connection: keep-alive

HTTP defines a set of request methods to indicate the desired action to be performed for a given resource. Here we use

  • The GET method requests a representation of the specified resource. Just after the word GET we see a URI pattern which is the name of the specific route requested on the HOST i.e. abs.com/requested_URL.
  • HTTP/1.1 is the protocol version.
  • User-Agent is the information of requesting web browser.
  • Accept tells the server about the file formats that the client is expecting.
  • Accept-Language tells the server about the languages understood by the client.
  • Connection tells us how long should the HTTP connection should be established.

And the Response… ?

Host checks for more information to process the request like headers values, the method GET, POST, PUT etc.Response sent by a server consists of a Header and a Body.

The response is then rendered by the requesting browser according to the Content-type field in the response header.

What is 200 OK ?

The first line is called the status line. It supplies the HTTP version, status code and status message. The status code informs the client of the status of the HTTP server’s response. In HTTP/1.1, 5 kinds of status codes were defined:

- 1xx Informational
- 2xx Success
- 3xx Redirection
- 4xx Client Error
- 5xx Server Error

Status codes are short way of server to tell client what’s the result of the request. We all have seen 404 : File not found and now we know what it is.

So what did we understand so far..?

The request-response cycle begins with a client sending a request message to a server. The server handles the request and sends a response message back to the client. An HTTP message has a header and sometimes a body. The header contains meta-information about the message. The body contains the content.

How Go works with web ?

We’ve discussed that web applications are based on the HTTP protocol, and Go provides full HTTP support in the net/http package. Let us first look into the http package working mechanism –

Understanding the Workflow :

  1. Create a listening socket, listen to a port and wait for clients.OK. But what is a socket ?
    A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent to.
  2. Accept requests from clients.And…how exactly all this is happening ?
    The client knows the host name of the machine on which the server is running and the port number on which the server is listening.
  1. The client also needs to identify itself to the server so it binds to a local port number that it will use during this connection. If everything goes well, the server accepts the connection.
  1. The client and server can now communicate by writing to or reading from their sockets.
  2. Handle requests, read HTTP header. If the request uses POST method, read data in the message body and pass them to handlers. Finally, socket returns response data to clients.

How does it maps to the real code ?

Go uses ListenAndServe to handle the steps:

  • Initialize a server object.
  • Call net.Listen("tcp", addr) to setup a TCP listener and
  • Listen to a specific address and port.

We can see that srv.Serve(net.Listener) is called to handle client requests. In the body of the function there is a for{}. It accepts a request, creates a new connection then starts a new goroutine, passing the request data to the go c.serve() goroutine. This is how Go supports high concurrency, and every goroutine is independent.
A goroutine is a lightweight thread managed by the Go runtime, to learn more about go routine follow : Concurrency in GO.
conn parses request c.ReadRequest() at first, then gets the corresponding handler: which is the second argument we passed when we called ListenAndServe. Because we passed nil, Go uses its default handler handler = DefaultServeMux.

So what is DefaultServeMux ?
Its the router variable which can call handler functions for specific URLs. For example http.HandleFunc("/", methodName). We’re using this function to register the router rule for the “/” path. When the URL is /, the router calls the function methodName. DefaultServeMux calls ServerHTTP to get handler functions for different paths, calling methodNamein this specific case.
Finally, the server writes data and responds to clients.

Here is a sample code to get you started and sum-up all the things discussed above:

package main
import (
"fmt"
"net/http"
)
func functionHandle(w http.ResponseWriter, r *http.Request) {
fmt.Println("Worked !")
}
func main() {
http.HandleFunc("/", functionHandle)
http.ListenAndServe(":8080", nil)
}

Running the code by “go run <filename>” will initialize a server listening at port 8080.

Hope now you have a better understanding of how things work on the Internet and how Golang’s simplicity helps in creating a simple web server. There is much more to web development via Golang but this is all to get your basics right and give you a head-start in the world of GO !
Happy coding :)

--

--

Archit Joshi

Software developer. New to writing. Always up for a workout :)