How to serve files and process form inputs with Go

in #programming7 years ago (edited)

This short tutorial will be about using Go to serve a file and process the form values submitted from the file using a "POST" action.

<p dir="auto"><img src="https://images.hive.blog/768x0/https://steemitimages.com/DQmVKtke9z2osyhBxTUk3Pyv2pK7S36xTk6GbLR97Kstzc7/golang-gopher-laptop.png" alt="golang-gopher-laptop.png" srcset="https://images.hive.blog/768x0/https://steemitimages.com/DQmVKtke9z2osyhBxTUk3Pyv2pK7S36xTk6GbLR97Kstzc7/golang-gopher-laptop.png 1x, https://images.hive.blog/1536x0/https://steemitimages.com/DQmVKtke9z2osyhBxTUk3Pyv2pK7S36xTk6GbLR97Kstzc7/golang-gopher-laptop.png 2x" /> <p dir="auto">The first step we need to take is create a directory and the files <code>main.go and <code>myform.gtpl inside the directory: <pre><code>/myform - main.go - myform.gtpl <p dir="auto">Create the contents of <code>myform.gtpl: <pre><code><html> <head> <title></title> </head> <body> <h2 style="text-align: center;">Go lang</h2> <form action="/show" method="POST"> <input type="text" name="task" /> <button type="submit">Show</button> </form> </body> </html> <p dir="auto">In the above, you can see the <code>action attribute of the form is assigned the string "/show" and the method is assigned the value "POST". The text input has the name attribute that has "task "assigned to it. <p dir="auto">Next inside our <code>main.go file, we import the necessary libraries and create the <code>main function and the <code>show http handler: <pre><code>package main import ( "fmt" "net/http" "html/template" ) func show() {} func main() {} <p dir="auto">The main function is where we will register our handler (<code>show) and Go's <code>DefaultServeMux internally (using <code>http.HandleFunc) and listen on the TCP network for incoming connections and call <code>Serve internally (using <code>http.ListenAndServe). We will be serving the files on port 9000: <pre><code>func main() { http.HandleFunc("/show", show); http.ListenAndServe(":9000", nil) } <p dir="auto">Then we implement the http handler 'show' in a couple of steps: <h2>Step 1 <pre><code>func show(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { t, _ := template.ParseFiles("show.gtpl") t.Execute(w, nil) } } <p dir="auto">We see in the above that the <code>show handler accepts two parameters, <code>w that is a type of the <code>http.ResponeWriter interface and <code>r that is a type of the <code>*http.Request struct which also has multiple properties such as <code>Method, <code>URL, <code>Header, <code>Body and etc. But, in our case, we are only interested in the <code>Method property for checking if the request is a <code>GET or another type of request such as <code>POST. <p dir="auto">If the method is <code>GET, then we invoke <code>ParseFiles on the <code>template and pass into it the name of the file we want and assign the returned value to the variable <code>t. According to the documentation, "ParseFiles is a method that creates a new template and parses the template definitions from the named files". On the template, we invoke <code>Execute(w, nil) to write the output to the IO writer. <h2>Step 2 <p dir="auto">If the request method is <code>POST, we will need to parse the submitted form and print the value. <p dir="auto">The request (r), has the method <code>ParseFrorm(), that will parse the form and populates <code>r.Form and <code>r.PostForm, which are maps on the the <code>r. Then we can do r.Form["task"], to the the value submitted. <pre><code>func show(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { t, _ := template.ParseFiles("show.gtpl") t.Execute(w, nil) } else { r.ParseForm() fmt.Println(r.Form["task"]) } } <p dir="auto">In conclusion, serving a file in Go is very simple; you only need two basic libraries ("html/template" and "net/http"). for accomplishing that task. In addition, you need to understand the http object, and the http.ResponseWriter interface and *http.Request struct and the properties they contain (such as Method in the case of *http.Request). You also need to understand how to parse files (know what the r.ParseFiles("fileName") method does), and the use of r.ParseForm() and how it populates r.Form. <p dir="auto">Here is the entire go code, without breaking it into snippets: <pre><code>package main import ( "fmt" "html/template" "net/http" ) func show(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { t, _ := template.ParseFiles("show.gtpl") t.Execute(w, nil) } else { r.ParseForm() fmt.Println(r.Form["task"]) } } func main() { http.HandleFunc("/show", show); http.ListenAndServe(":9000", nil) } <p dir="auto">References: <p dir="auto"><br /><br /><span><a href="https://golang.org/pkg/net/http/" target="_blank" rel="nofollow noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://golang.org/pkg/net/http/<span> <a href="https://golang.org/pkg/html/template/#Template.Execute" target="_blank" rel="nofollow noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://golang.org/pkg/html/template/#Template.Execute<span> <a href="https://astaxie.gitbooks.io/build-web-application-with-golang/en/" target="_blank" rel="nofollow noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">https://astaxie.gitbooks.io/build-web-application-with-golang/en/