Go is a popular programming language that was created by Google in 2009. Go, also known as Golang, is a statically typed and compiled language that is designed for efficient and concurrent programming. Go is an excellent choice for building web applications due to its simplicity, performance, and built-in support for concurrency. In this tutorial, we will learn how to build a simple web application with Go.

Prerequisites

Before we begin, you will need to have Go installed on your computer. You can download and install Go from the official website at https://golang.org/dl/. You will also need a text editor to write your Go code. We recommend using Visual Studio Code with the Go extension.

Getting Started

To get started, create a new directory for your project. We will call our project "go-web-app". Inside this directory, create a new file called "main.go". This file will contain the main code for our web application.

Open "main.go" in your text editor and add the following code:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", home)
	http.ListenAndServe(":8080", nil)
}

func home(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, World!")
}

This code creates a new web server that listens on port 8080. When a user visits the home page "/", the server will call the "home" function, which will write the text "Hello, World!" to the user's browser.

Running the Web Application

To run the web application, open a terminal window and navigate to the "go-web-app" directory. Type the following command:

go run main.go

This will compile and run the "main.go" file. You should see output similar to the following:

Listening on :8080...

Open a web browser and navigate to http://localhost:8080. You should see the text "Hello, World!" displayed in the browser.


Handling Requests and Responses

Let's modify our code to handle requests and responses. Replace the "home" function with the following code:

func home(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	fmt.Fprintf(w, "<h1>Welcome to my website!</h1>")
}

This code sets the "Content-Type" header to "text/html" and writes an HTML heading to the user's browser.

Now let's add a new route to handle a contact page. Add the following code to your "main.go" file:

func contact(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	fmt.Fprintf(w, "<h1>Contact Us</h1><p>Send us a message!</p>")
}

func main() {
	http.HandleFunc("/", home)
	http.HandleFunc("/contact", contact)
	http.ListenAndServe(":8080", nil)
}

This code adds a new route for the "/contact" URL. When a user visits this page, the "contact" function will be called, which will write an HTML heading and paragraph to the user's browser.

Save your changes and restart the web server by running the "go run main.go" command again. Open a web browser and navigate to http://localhost:8080/contact. You should see the text "Contact Us" and "Send us a message!" displayed in the browser.

Creating Templates

Let's create a template for our web pages so that we can reuse code and separate our presentation from our logic. Create a new directory called "templates" inside your "go-web-app" directory. Inside the "templates" directory, create a new file called "base.html". This file will contain the basic HTML structure for our web pages. Add the following code to "base.html":

<!doctype html>
<html>
  <head>
    <title>{{ .Title }}</title>
  </head>
  <body>
    <nav>
      <a href="/">Home</a>
      <a href="/contact">Contact Us</a>
    </nav>
    <main>
      {{ template "content" . }}
    </main>
  </body>
</html>

This code defines the basic HTML structure for our web pages, including a navigation menu and a placeholder for the main content. The {{ .Title }} and {{ template "content" . }} are placeholders that will be replaced with actual content when we render our pages.

Next, create a new file called "home.html" inside the "templates" directory. This file will contain the HTML content for our home page. Add the following code to "home.html":

{{ define "content" }}
  <h1>Welcome to my website!</h1>
{{ end }}

This code defines the content for our home page, which will be inserted into the {{ template "content" . }} placeholder in "base.html".

Finally, create a new file called "contact.html" inside the "templates" directory. This file will contain the HTML content for our contact page. Add the following code to "contact.html":

{{ define "content" }}
  <h1>Contact Us</h1>
  <p>Send us a message!</p>
  <form>
    <label for="name">Name:</label>
    <input type="text" id="name" name="name">
    <br>
    <label for="email">Email:</label>
    <input type="email" id="email" name="email">
    <br>
    <label for="message">Message:</label>
    <textarea id="message" name="message"></textarea>
    <br>
    <button type="submit">Send</button>
  </form>
{{ end }}

This code defines the content for our contact page, including a form for users to send us a message.

Now we need to modify our code to render our templates. Replace the "home" and "contact" functions with the following code:

func home(w http.ResponseWriter, r *http.Request) {
	data := struct {
		Title string
	}{
		Title: "Home",
	}
	renderTemplate(w, "home", data)
}

func contact(w http.ResponseWriter, r *http.Request) {
	data := struct {
		Title string
	}{
		Title: "Contact Us",
	}
	renderTemplate(w, "contact", data)
}

func renderTemplate(w http.ResponseWriter, tmpl string, data interface{}) {
	tmpl = fmt.Sprintf("templates/%s.html", tmpl)
	t, err := template.ParseFiles(tmpl, "templates/base.html")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	err = t.ExecuteTemplate(w, "base", data)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

This code defines a new "renderTemplate" function that will render our templates using the data we pass in. The "home" and "contact" functions now create a new "data" struct and pass it to the "renderTemplate" function along with the name of the template to render.

Save your changes and restart the web server by running the "go run main.go" command again. Open a web browser and navigate to http://localhost:8080 and http://localhost:8080/contact to see your home and contact pages respectively.

Congratulations! You've just built a simple web application using Go programming. While this example is quite basic, it demonstrates how Go can be used to build powerful and scalable web applications.

As you continue to learn and explore Go programming, you can explore more advanced topics such as using database systems, creating RESTful APIs, and implementing authentication and authorization systems. There are also many third-party packages and libraries available that can help you build more complex web applications with Go.

Conclusion

Go is a powerful and flexible programming language that is well-suited for building web applications. With its built-in concurrency support, fast compile times, and efficient memory management, Go is a great choice for developing high-performance web applications.

In this tutorial, you learned how to build a simple web application using Go programming. You learned how to use the net/http package to create a web server and handle HTTP requests, as well as how to use the html/template package to render dynamic HTML pages.

Remember that this is just the beginning of your journey with Go programming. There is much more to learn and explore, and with practice and perseverance, you can become a skilled and proficient Go developer. Happy coding!