Create A Simple Web App In GoLang

Introduction
In this article, I would like to create a simple web app in GoLang (in short Go) programming language. Go is a statically typed, compiled programming language designed at Google. As the official website of GoLang says,
Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
Go official website
You can learn more about GoLang from its official website: https://golang.org/
Without further ado, let’s dive into our app.
Install GoLang
You can install golang from its official website with this link here: https://golang.org/dl/ . Also, make sure that you have installed it correctly and set GOPATH
as an environment variable. To clarify the doubt, check with following command.
A quick note: Use GoLand IDE if possible.
In Linux
echo $GOPATH
In Windows
echo %GOPATH%
Create Project Directory
Now, we have to create a directory inside src
folder of the GOPATH
. If there is not an src
folder, then you have to create one. Therefore, let’s create a directory called demo
mkdir $GOPATH/src/demo
cd $GOPATH/src/demo
Inside the directory we have to create a demo.go
file which will be the main file for our app and write some lines of code.
package main // For executable package, we use main import ( "fmt" "log" "net/http" "os" "demo/handlers" // Created own package for handling routes ) // Main program starts here func main() { // Handling Routes http.HandleFunc("/", handlers.IndexHandler) http.HandleFunc("/users", handlers.UserHandler) // Use environment variable "PORT" or otherwise assign port := os.Getenv("PORT") if port == "" { port = "8080" log.Printf("The port is %s", port) } // Logging log.Printf("Listening on port %s", port) log.Printf("Open http://localhost:%s in the browser", port) // Create server or exit log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) }
Handlers
I don’t like to include all of the codes in a single files, hence I would like to create a new directory named handlers
and inside the directory create a file handlers.go
as follows:
package handlers import ( "fmt" "net/http" ) // We need ResponseWriter for sending response, and Request for handling request func IndexHandler(w http.ResponseWriter, r *http.Request) { // If following code is emitted, the url other than '/' will be handled as same if r.URL.Path != "/" { http.NotFound(w, r) return } _, err := fmt.Fprint(w, "Welcome To NepCodex.com") if err != nil { w.WriteHeader(http.StatusInternalServerError) } } // Similarly, for '/users' func UserHandler(w http.ResponseWriter, r *http.Request) { _, err := fmt.Fprint(w, "Hello User From Users Page, NepCodex.com") if err != nil { w.WriteHeader(http.StatusInternalServerError) } }
Templates
Up to this we created a simple response sending application, which you can test using go run todo.go
command. However, this is not enough for us because it is the simplest web app one can create in GoLang. Therefore, let’s create an html index.html
inside a folder named templates
.
mkdir templates
cd templates
touch index.html # or notepad index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>NepCodex Demo - {{.PageTitle}}</title> <link rel="stylesheet" href="/static/styles.css"> </head> <body> <h1>Hello Demo App </h1> <div> <h2>{{if.Heading}} {{.Heading}} {{else}} DeMo - (Default Heading) {{end}}</h2> <!-- Implementing IF ELSE example --> <li><b>Name</b>: {{.Name}}</li> <li><b>Country</b>: {{.Country}}</li> </div> </body> </html>
In the code above, the {{}}
encloses the variables, or programming logic.
At the same time, let’s create a stylesheet styles.css
in /static/
folder inside the root directory. Assume I am in demo
folder, i.e. root folder.
mkdir static
cd static
Then, create a directory and inside it create a styles.css
file with some styles:
body { padding: 50px; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; } a { color: #00B7FF; }
Further, we have to handle the static
folder with URLs. For that, I have included following lines of code in demo.go
file.
... // Handle Static Content http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) ...
Now, let’s create another file named renderTemplate.go
which will be responsible for showing views.
package handlers import ( "html/template" "net/http" ) // Parse template files var templates = template.Must(template.ParseFiles("templates/index.html")) // Declaration of struct needed for the template type Page struct { PageTitle string Heading string Name string Country string } // A custom render function which takes the filename of template html file func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { err := templates.ExecuteTemplate(w, tmpl+".html", p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
Again, we have to handle our Index
page for the URL /
. Hence, for the purpose, make some changes inside handlers.go
file and IndexHandler
function.
... // We need ResponseWriter for sending response, and Request for handling request func IndexHandler(w http.ResponseWriter, r *http.Request) { // If following code is emitted, the url other than '/' will be handled as same if r.URL.Path != "/" { http.NotFound(w, r) return } p := &Page{ PageTitle: "Demo Home Page", Heading: "", // Change this to something else and see the results in html page Name: "NepCodex", Country: "Nepal", } renderTemplate(w, "index", p) } ...
Now re-run the application and see the output.
Conclusion
Hence, in this way we created a simple web app in GoLang. I hope it gave you some insights on how GoLang works. As you have seen that, there is no serial execution like many other programs, instead it executes concurrently. That is why, Google Developed GoLang for its ease.
If you would like to learn about Laravel, check it out here: https://nepcodex.com/blog/2019/07/laravel-is-it-a-choice-for-web-artisans/
Also, you can learn about Rest API in Django from here: https://nepcodex.com/blog/2019/07/django-rest-api-from-scratch-part-1/