Go is a general purpose programming language, compiled and statically typed with a clean syntax and advanced features. Its performance and design has been making it the favorite language of fin-tech companies. Despite all its benefits, Go lang stills alien for many developers across the community so we’ll try to change that here.

If you haven’t “break the ice” with Go, please just take this 5 minutes post to demonstrate the simplicity and ease of Go. You won’t regret it.

Assuming an environment within Docker

We’ll take an already prepared environment from a previous post, so please refer to it if you haven’t read it:

The Specs

Our HTTP server will have to be capable of fulfill three key tasks:

Process dynamic request: Process incoming requests that follows HTTP standard from any kind of client (users or other services). Serve static assets: Serve Javascript files, CSS files and images to clients, commonly Web browsers. Accept connections: HTTP server should listen to incoming connections on a specific port.

That being said, let’s begin with our code.

The Main file

In order to follow Go conventions we’ll create a main.go file declaring the “main” package, importing the two required packages we’ll need ( fmt and net/http ) and declaring the standard main method that will be our application’s entry point:

package main import (

"fmt"

"net/http"

) func main() {

}

All our business logic will go inside main function. Now let’s begin with the implementation of our specs.

Process dynamic requests

We’ll rely on a Go’s core library/package called net/http that contains all the functionalities we need to handle requests dynamically. The first thing to do is to register a new handler for every route we want have using http.HandleFunc function. This function accepts two parameters: The first one is a string representing the path to match and the second a function that will be executed to handle the request.

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

fmt.Fprintf(w, "This is a website server by a Go HTTP server.")

})

This is a pretty common pattern across all REST API frameworks. Please notice how the provided function as second parameter receives two services as parameters (by dependency injection); One to handle the response ( http.ResponseWriter ) and another ( http.Request ) to get any data or value from the request. With this second service we can read GET parameters with r.URL.Query().Get("keyword") or POST parameters in request body with r.Body .

Serve static assets

Next thing to do is to serve static assets that commonly are Javascript or CSS files as well as images. To do this we’ll use http.FileServer from net/http package and point it to a URL path by passing to it the directory where the files to be served will be located:

fs := http.FileServer(http.Dir("static/"))

Now the variable fs hold the instance of the static assets internal server, so now we just need to map it to an URL path just like we did before with dynamic requests:

http.Handle("/static/", http.StripPrefix("/static/", fs))

Please notice that we are using an additional method http.StripPrefix this in order to strip away part of the URL path to correctly serve files from system.

Accept connections

We’ll are almost done and the last part to do here is to listen for and accept incoming connections from clients across the network/Internet. To do this, we’ll rely again on Go’s inbuilt net/http package:

http.ListenAndServe(":3001", nil)

By this mean we are indicating our Go application to listen any incoming request on port 3001 ( gin package uses this server to listen by default).

Try it!

Now run docker to start our server container:

docker-compose up

Once having the server running, go to your browser and navigate to localhost:3030 . You’ll see a text “This is a website server by a Go HTTP server.” which means that your server is up and running properly.

Additional routes

Finally and as a plus, let’s add an additional route an see what happens:

http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {

fmt.Fprintf(w, "Hello World! I'm a HTTP server!")

})

As you can see, here we are adding a little larger path instead of just “/” and then serving a different text. Keep in mind to register this function before http.ListenAndServe(“:3001”, nil) .

Once you’ve added this code, wait for auto reload to finish in container’s stdout console:

go-expense-api | [gin] Building...

go-expense-api | [gin] Build finished

Now go to your browser and now navigate to localhost:3030/hello in order to see that “hello world”.

The code

With all this, our resulting HTTP server application project will result as follows:

Summary

In this edition we “broke the ice” with Go by creating a super minimum (but fully functional) HTTP server capable of processing dynamic request, serve static assets and listen for incoming request from clients. From this point is easy to see how thing could be coming on with Go.