Hello Go Webserver!
Let’s spin up a simple webserver using Golang to handle HTTP requests and serve HTML content rendered from template files.
Prerequisites:
Working go
installation1
Part 1: Basic webserver
Create a directory for the project (mine is named websrv-proj
) and place the following in a file named main.go
.
~/websrv-proj/main.go
package main
import (
"fmt"
"log"
"net/http"
)
// baseHandler is run when the server receives a request to the
// "<server-address>:<server-port>/" url route.
func baseHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello World!")
}
// main() registers http handlers, and starts listening for inbound TCP
// requests on port `:8888`.
func main() {
http.HandleFunc("/", baseHandler)
log.Fatal(http.ListenAndServe(":8888", nil))
}
We can run this script and make requests to the server via command line or web browser.
~/websrv-proj
$ go run main.go &
$ curl http://localhost:8888/
Hello World!
Part 2: Render HTML from Template
Okay, so we have a server listening on a port and it’s ready to handle requests to the “/” route. Let’s make this a webpage and return some HTML instead of a string. Let’s create a simple template file2 in the project directory.
~/websrv-proj/index.html.tmpl
<!doctype html>
<html>
<head>
</head>
<body>
<div>
<p>{{ . }}</p>
</div>
</body>
</html>
- Now we have a template file that’s expecting a single template variable as input. We can update the handler to execure the template with a string argument and return the rendered HTML.
func handler(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("index.html.tmpl")
t.Execute(w, "Hello World!"); err != nil {
}
Part 3: Extend the HTML template
- We can update our template to make it easier to add new functionality.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="site">
<title>site</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
</head>
<body>
<main class="container" style="padding: 25px;">
<div>
<figure class="text-center">
<blockquote class="blockquote">
<p>{{ . }}</p>
</blockquote>
</figure>
</div>
</main>
</body>
</html>
Wrapping up
At this point we should have an HTTP server listening for requests to the
/
route on port :8888
.
What next?
- refactor into a module
- add more pages and content
- change the bootstrap theme / general styling
- use a web framework / middleware package with more features
- deploy on a cloud provider (Digital Ocean, Heroku, etc)
- add a form and do something with the input
- …