Learn go series: Part I - Hello World as a service
This is Part 1 of “Learn go” series. This series assumes you have a general familiarity of the golang syntax and types. If not, I urge you to follow the interactive tour of go and/or watch Russ Cox’s video
In this post, I will be walking you through an example of writing a Hello World json end point. So lets begin with…
A Simple “Hello World!“
main.go
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
Now compiling it as:
$ go build -o main
and running:
$ ./main
Hello World!
Alternatively, you can skip the above using:
$ go run main.go
Hello World!
As with many other languages, golang begins execution with main function. By convention, functions to be exported begin with capital letters. Here, we have imported fmt package which exports Println function.
Intro to native net/http
I have been dabbling with go for almost a month now, and honestly, the entire language feels like a web framework. It has a ton of niceness baked right into it. You can pretty much skip importing libraries for most tasks. Let me give you an example of writing a native API from golang docs
main.go
package main
import (
"encoding/json"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
response := map[string]string{"hello": "world"}
json.NewEncoder(w).Encode(response)
}
func main() {
http.HandleFunc("/hello/", helloHandler)
http.ListenAndServe(":8080", nil)
}
$ go run main.go
Ensure the server has started by running the following:
$ curl http://localhost:8080/hello/
{"hello":"world"}
As you can see, this works pretty well and we didn’t even import any third-party libraries. Hold on, we aren’t done yet though. Let’s say I want the API to look like: http://localhost:8000/hello/{yourName}. Or I only want it to work with GET method. I have some other functionality in mind for POST.
It is quite possible with the native HandleFunc and the handler functions to add these functionality (cough switch case cough), but the code quickly becomes unwieldy. Let me walk you through one of my favorite solutions for such occasions - mux from the Gorilla toolkit.
Entering Skull Island
Although, there are several other web “frameworks” in golang. My favorite by far is a little routing library called “mux”. It is from the Gorilla toolkit which has several other useful web packages.
$ go get github.com/gorilla/mux
Now rewriting, as follows:
main.go
package main
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
response := map[string]string{"hello": "world"}
json.NewEncoder(w).Encode(response)
}
func helloNameHandler(w http.ResponseWriter, r *http.Request) {
response := map[string]string{"hello": mux.Vars(r)["yourName"]}
json.NewEncoder(w).Encode(response)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/hello", helloHandler).Methods("GET")
router.HandleFunc("/hello/{yourName}", helloNameHandler).Methods("GET")
http.ListenAndServe(":8080", router)
}
As before, run it:
$ go run main.go
Now you can access:
$ curl http://localhost:8080/hello # {"hello": "world"}
$ curl http://localhost:8080/hello/Gaurav # {"hello": "Gaurav"}
Honorable mentions & caveats
- Glide - Go Package Manager
- Gin - To auto reload server during development. Not to be confused with gin web framework
- Go expects all source code to be namespaced and located within $GOPATH/src directory. For eg:
https://github.com/algogrit/go-examplewill be in$GOPATH/src/github.com/algogrit/go-example
As always leave your thoughts in the comments section below. In the next post, I will be covering a go ORM called gorm.
Related Articles
Learn go series: Part IV - Project Structuring
Part 4 of Learn Go - a simple, practical guide to structuring Go projects—clean packages, clear responsibilities, and no “everything in main.go” chaos.
Learn go series: Part II - Gorm up!
Part 2 of Learn Go - build a real signup API using Go, PostgreSQL, and GORM—covering schema design, database setup, and secure password hashing.