Building a Go Web App from Scratch to Deploying on Google Cloud | Part #1 - Building a Simple Go Web App from Scratch.

Go short for golang, is a statically compiled language. It’s language structure resembles that of C/C++ with heavy emphasis placed on terse statements and removal of boilerplate most older languages carry around. Wikipedia article describes more motivations behind go:

It is slowly becoming the de-facto language of choice for building backend server applications such as Kubernetes, Docker, Traefik, Prometheus, etcd etc. In this article we build a simple HTML/CSS website, that greets us with the time and shows a cool background photo. I’ll demonstrate everything from scratch.

Step 1: Install golang

Follow the link to the official golang website to select your platform and associated installation instructions. This is a simple step in most cases. When installing, ensure you define your GOPATH and remember it. This is the path typically all your go projects get stored in, you can choose the GOPATH to point anywhere on your file system.

https://golang.org/doc/install

Step 2: Setup our directory structure

Once installed, let us change directory to our GOPATH. To find your GOPATH on Linux. Type in the following command

env | grep GOPATH

For instance mine is found on /home/<my-username>/go/ on my Linux machine. Let’s check into it

cd $GOPATH

Within this directory we either find it empty or that it contains two folders, a bin and a src folder. If your GOPATH directory is empty, create these two folders. Then check into the src folder.

cd src

Create a folder called welcome-app and check into it.

mkdir welcome-app
cd welcome-app

Your directory structure should look something like this

/home
/<your-username>
/go
bin/
//Empty for now
src/
/welcome-app

Note: (My directory is slightly different for the purposes of packaging of this tutorial, so long as you create this app in thego/src directory you should be good to go)

~/go/src/github.com/martinomburajr/medium/building-a-go-web-app-from-scratch-to-deploying-on-google-cloud/welcome-app

Step 2: Build the Front End

Before we dive into the actual code, let’s quickly set up the front end. The goal of this tutorial is to ensure the front end is as simple as possible so we can focus on the go server code. In most go applications, html code is usually placed within a template folder, this is not a must, but it helps us organize our code a bit.

//create a template directory in ~/go/src/welcome-app for our html
mkdir template
//create a static/stylesheets directory in ~/go/src/welcome-app for our css
mkdir -p static/stylesheets
//Open's Visual Studio code, you can open any text editor of choice code .

In thetemplate directory, I create the welcome-template.html. I also downloaded a stock photo from Pexels, but you can download a photo from any other free site e.g. Pikwizard. I then named thatit background. In the static/stylesheets directory, I create welcome-template.css.

Your directory should look something like this.

Don’t worry about the app.yaml, Dockerfile and other directory

I’m not going to dive into detail of the HTML and CSS, just copy the code below into the respective files you just created.

2.1 Html

templates/welcome-template.html
<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/stylesheets/welcome-template.css">

<!-- The welcome struct (shown in the main.go code) is received within the HTML and we just need to use the . operator and retrieve the information we want -->
<title>Welcome {{.Name}}</title>
</head>
<body>
<div class="welcome center">Welcome {{.Name}}, it is {{.Time}}</div>
</body>
</html>

2.2 CSS

static/stylesheets/welcome-template.css
body  {
min-height:100%;
background-image: url("/static/stylesheets/background.jpeg"), linear-gradient(rgba(0,0,0,0.2),rgba(0,0,0,0.3));
background-blend-mode: overlay;
background-size:cover
}

.welcome {
font-family: 'Segoe UI', 'Tahoma', 'Geneva', 'Verdana', 'sans-serif';
font-size: 3rem;
color: aliceblue;
}

.center {
height: 100vh;
display: flex;
justify-content: center;
align-items: center
}​

2.3 A cool background photo

background.jpeg | Photo from Pexels | Ylanite Koppens
Your directory should resemble this but without the Dockerfile, app.yaml and other directory

Step 3: Go Server Logic!

The time has come! Let’s implement some logic, and talk about what it takes to build a go server. I’ve added explanations of everything in the comments. (A code gist is provided at the end of the article for better formatting)

package main
We import 4 important libraries
1. “net/http” to access the core go http functionality
2. “fmt” for formatting our text
3. “html/template” a library that allows us to interact with our html file.
4. "time" - a library for working with date and time.
import (
"net/http"
"fmt"
"time"
"html/template"
)


//Create a struct that holds information to be displayed in our HTML file
type Welcome struct {
Name string
Time string
}


//Go application entrypoint
func main() {
//Instantiate a Welcome struct object and pass in some random information.
//We shall get the name of the user as a query parameter from the URL
welcome := Welcome{"Anonymous", time.Now().Format(time.Stamp)}

//We tell Go exactly where we can find our html file. We ask Go to parse the html file (Notice
// the relative path). We wrap it in a call to template.Must() which handles any errors and halts if there are fatal errors

templates := template.Must(template.ParseFiles("templates/welcome-template.html"))

//Our HTML comes with CSS that go needs to provide when we run the app. Here we tell go to create
// a handle that looks in the static directory, go then uses the "/static/" as a url that our
//html can refer to when looking for our css and other files.

http.Handle("/static/", //final url can be anything
http.StripPrefix("/static/",
http.FileServer(http.Dir("static"))))
//Go looks in the relative "static" directory first using http.FileServer(), then matches it to a
//url of our choice as shown in http.Handle("/static/"). This url is what we need when referencing our css files
//once the server begins. Our html code would therefore be <link rel="stylesheet" href="/static/stylesheet/...">
//It is important to note the url in http.Handle can be whatever we like, so long as we are consistent.

//This method takes in the URL path "/" and a function that takes in a response writer, and a http request.
http.HandleFunc("/" , func(w http.ResponseWriter, r *http.Request) {

//Takes the name from the URL query e.g ?name=Martin, will set welcome.Name = Martin.
if name := r.FormValue("name"); name != "" {
welcome.Name = name;
}

//If errors show an internal server error message
//I also pass the welcome struct to the welcome-template.html file.
      if err := templates.ExecuteTemplate(w, "welcome-template.html", welcome); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})


//Start the web server, set the port to listen to 8080. Without a path it assumes localhost
//Print any errors from starting the webserver using fmt
fmt.Println("Listening");
fmt.Println(http.ListenAndServe(":8080", nil));

}

Step 4: Run our application.

We have everything we need for our application to run. Check into the project path and in the terminal type.

go run main.go

This will start the server on port 8080. Navigate to localhost:8080 on your web browser.

Final Application

To show your name, type in ?name=your-name-here. There you have it, a fully functional go web application! If you want the entire repository, clone it here

Conclusion

In this tutorial, we created a simple Go web application that welcomed us and gave us the date and time. We went through how to use parts of the net/http library to serve both templates as well as additional files for a particular route. In the next tutorial we see how we can launch this Go application on Google’s App Engine, which is a managed platform as a service that allows developers to bring their code and Google focuses on its availability and security.

Appendix

The main.go gist