Original

Introduction

Go is a battery included programming language and has a webserver already built
in.

The net/http package from the standard library contains all functionalities
about the HTTP protocol.

This includes an HTTP client and an HTTP server.

Registering a Request Handler

First, create a Handler which receives all incoming HTTP connections from
browsers, HTTP client or API requests. A handler in Go is a function with this
signature.

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

The function receives two parameters:

  • An http.ResponseWriter which is where you write your text/html response to.

  • An http.Request which contains all information about this HTTP request
    including like URL or header fields

Registering a request handler to the default HTTP Server is as simple as this:

1
2
3
http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
})

Listen for HTTP Connections

The request handler alone can not accept any HTTP connections from the outside.

An HTTP server has to listen on a port to pass connections on to the request
handler. Because port 80 is in most case the default port for HTTP traffic, this
server will also listen on it.

The following code will start Go’s default HTTP server and listen for
connections on port 80. You can navigate your browser to http://localhost/ and
see your server handling yoru request

1
http.ListenAndServe(":80", nil)

The Code

1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
"fmt"
"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)
})
http.ListenAndServe(":80", nil)
}

Routing (using gorilla/mux)

Go’s net/http package provides a lot of functionalities for the HTTP protocol.
One thing it doesn’t do very well is complex request routing like segmenting a
request url into single parameters.

Use gorilla/mux package to create routes with named parameters, GET/POST
handlers and domain restrictions.

gorilla/mux is a package which adapts to Go’s default HTTP router. It comes
with a lot of features to increase the productivity when writing web
applications. It is also compliant to Go’s default request handler signature
func (w http.ResponseWriter, r *http.Request), so package can be mixed and
matched with other HTTP libraries like middleware or existing applications. Use
the go get command to install the package from Github.

1
go get -u github.com/gorilla/mux

Creating a new Router

First create a new request router. The router is the main router for your web
application and will later be passed as parameter to the server. It will receive
all HTTP connections and pass it on to the request handlers you will register on
it. You can create a new router like so:

1
r := mux.NewRouter()

Registering a Request Handler

Once you have a new router you can register request handlers like usual. The
only difference is that instead of calling http.HandleFunc(...), you call
HandleFunc on your router like this r.HandleFunc(...)

URL Parameters

The biggest strength of the gorilla/mux Router is the ability to extract
segments from the request URL. As an example, this is a URL in your application

1
/books/go-programming-bluepring/page/10
1
2
3
4
r.HandleFunc("/books/{title}/page/{page}", func (w http.ResponseWriter, r *http.Request) {
// get the book
// navigate to the page
})

The last thing to get the data from these segments. The package comes with the
function mux.Vars(r) which takes the http.Request as parameter and returns a
map of the segments.

1
2
3
4
5
func (w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
vars["title"]
vars["page"]
}

Setting the HTTP server’s router

Ever wondered what the nil in http.ListenAndServe(":80", nil) ment? It is
the parameter for the main router of the HTTP server. By default it’s nil,
which means to use the default router of the net/http package. To make use of
your own router, replace the nil with the variable of your router r.

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

The Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)

func main () {
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)
}

Features of the gorilla/mux Router

Methods

Restrict the request handler to specific HTTP methods

1
2
3
4
r.HandleFunc("/books/{title}", CreateBook).Methods("POST")
r.HandleFunc("/books/{title}", ReadBook).Methods("GET")
r.HandleFunc("/books/{title}", UpdateBook).Methods("PUT")
r.HandleFunc("/books/{title}", DeleteBook).Methods("DELETE")
Hostnames & Subdomains

Restrict the request handler to specific hostname or subdomain

1
r.HandleFunc("/books/{title}", BookHandler).Host("www.mybookstore.com")
Schemes

Restrict the request handler to http/https

1
2
r.HandleFunc("/secure", SecureHandler).Scheme("https")
r.HandleFunc("/insecure", InsecureHandler).Scheme("http")
Path Prefixes & Subrouters

Restrict the request handler to specific path prefixes.

1
2
3
bookrouter := r.Path.Prefix("/books").subRouter()
bookrouter.HandleFunc("/", AllBooks)
bookrouter.HandleFunc("/{title}", GetBook)

Template

Go’s html/template package provides a rich templating language for HTML
templates. It is mostly used in web applications to display data in a structured
way in a client’s browser. One great benefit of Go’s templating language is the
automatic escaping of data. There is no need to worry about XSS attacka as Go
parses the HTML template and escapes all inputs before displaying it to the
browser.

First Template