Menu
  • Home
  • About Me
  • Blog
  • Github
  • LinkedIn

Building Containerized Microservices in Golang Chapter 2 – Web Development

May 12, 2022

Let’s create simple webserver that you can view in your browser using net/http

This function is going to take the request and give responses as well:

func (w http.ResponseWriter, r *http.Request)

The request handler alone can not accept any HTTP connections from the outside. To listen for HTTP Connections, following code will start Go’s default HTTP server and listen for connections on port 80:

http.ListenAndServe(":80", nil)

Example Code:

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
	})
	// listening on port 80
	log.Println("Web Server has started")
	http.ListenAndServe(":80", nil)
}
// reference : https://gowebexamples.com/hello-world/

You will see this message on your browser

Process Dynamic request

I’m going to parse a parameter or a URL query parameter called token.

r.URL.Query().Get("token")
http://localhost/hello?token=222

Serving static assets

create folder named static and file named index.html

// static/index.html
<html>
    <head>
        <title> Sean Lim</title>
    </head>
<body>
    <h2>Website using GO</h2>
</body>
</html>
package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, you've requested: %s with token: %s\n", r.URL.Path, r.URL.Query().Get("token"))
	})
	// create file server
	fs := http.FileServer(http.Dir("static/"))
	http.Handle("/static/", http.StripPrefix("/static/", fs))

	// listening on port 80
	log.Println("Web Server has started")
	http.ListenAndServe(":80", nil)
}

You can create separate function like this as well:

package main

import (
	"fmt"
	"log"
	"net/http"
)

func rootHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, you've requested: %s with token: %s\n", r.URL.Path, r.URL.Query().Get("token"))
}

func main() {
	http.HandleFunc("/", rootHandler)

	// create file server
	fs := http.FileServer(http.Dir("static/"))
	http.Handle("/static/", http.StripPrefix("/static/", fs))

	// listening on port 80
	log.Println("Web Server has started")
	http.ListenAndServe(":80", nil)
}

Routing using gorilla/mux

install the gorilla/mux package:

go get -u github.com/gorilla/mux

Create a new router which is going to handle all the incoming requests and pass it to the various handlers.

package main

import (
    "fmt"
    "net/http"

    // you need to install the package
    "github.com/gorilla/mux"
)

func main() {

    // create a new router
    r := mux.NewRouter()

    r.HandleFunc("/books/{title}/page/{page}", func(w http.ResponseWriter, r *http.Request) {
        vars := mux.Vars(r)
        title := vars["title"]
        page := vars["page"]

        fmt.Fprintf(w, "You've requested the book: %s on page %s\n", title, page)
    })

    http.ListenAndServe(":80", r)
}

create various handlers

package main

import (
	"encoding/json"
	"log"
	"net/http"
	"time"

	// you need to install the package
	"github.com/gorilla/mux"
)

func healthHandler(w http.ResponseWriter, r *http.Request) {
	// print some information
	log.Println("Checking application health")
	response := map[string]string{
		"status":    "UP",
                // put .String() since the type of map is set as string.
		"timestamp": time.Now().String(),
	}
	// encoding the response "w"
	json.NewEncoder(w).Encode(response)
}

func main() {

	// create a new router
	r := mux.NewRouter()

	r.HandleFunc("/health", healthHandler)

	log.Fatal(http.ListenAndServe(":80", r))
}

Create a root handler and get status of website


func rootHandler(w http.ResponseWriter, r *http.Request) {
	// print http success status
	log.Println("Serving the homepage")
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "Application is up and running")
}


func main() {
	r.HandleFunc("/", rootHandler)
}

Create one more function to fetching details of information. I’m going to create a separate package.

// details/details.go

package details

import "os"

func GetHostname() (string, error) {
	hostname, err := os.Hostname()

	return hostname, err
}
// main.go
// import detail package
details "github.com/sikgyu/go-microservices/details"

func detailsHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Fetching the details")
	hostname, err := details.GetHostname()
	// if error is not nil, create an exception (panic)
	if err != nil {
		panic(err)
	}
	// print hostname if there's no error
	fmt.Println(hostname)
}

func main() {
	r.HandleFunc("/details", detailsHandler)
}
// details/details.go

// Get preferred outbound ip of this machine
func GetIP() (net.IP, error) {
	conn, err := net.Dial("udp", "8.8.8.8:80")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	localAddr := conn.LocalAddr().(*net.UDPAddr)
	return localAddr.IP, err
}

Get IP address

You can refer to my Github repo.

Let’s serve this as a json response

func detailsHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Fetching the details")
	hostname, err := details.GetHostname()
	// if error is not nil, create an exception (panic)
	if err != nil {
		panic(err)
	}
	// print hostname and IP address if there's no error
	IP, _ := details.GetIP()
	fmt.Println(hostname, IP)
	response := map[string]string{
		"hostname": hostname,
		"ip":       IP.String(),
	}
	json.NewEncoder(w).Encode(response)
}

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts
  • ChinguTalkBot v0.1.0: Setting up AWS Cognito with CDK for User Authentication
  • Phoenix & Elixir: Fix PostgreSQL connection refused
  • Demo: Git Log with Shell script to create a release notes
  • Metasploit
  • CyberSecurity Lab – Online Password Attack

Archives
  • March 2024
  • May 2023
  • April 2023
  • February 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
Categories
  • Amazon Interview (3)
  • Ansible (3)
  • AWS (9)
  • Azure (9)
  • Certification (2)
  • ChinguTalkBot Project (1)
  • cybersecurity (3)
  • Data analytics (6)
  • Demo Videos (6)
  • Docker (5)
  • Git (1)
  • GitLab (1)
  • Golang (3)
  • JavaScript (2)
  • Jenkins (4)
  • PowerShell (1)
  • Python (10)
  • Terraform (11)
  • Uncategorized (9)

©2025 | Powered by WordPress and Superb Themes!