The following steps cover the writing and running of your application:
- From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter8/handlers, and navigate to this directory.
- Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter8/handlers
You should see a file called go.mod that contains the following:
module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter8/handlers
- Copy tests from ~/projects/go-programming-cookbook-original/chapter8/handlers, or use this as an exercise to write some of your own code!
- Create a file called get.go with the following contents:
package handlers
import (
"fmt"
"net/http"
)
// HelloHandler takes a GET parameter "name" and responds
// with Hello <name>! in plaintext
func HelloHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
name := r.URL.Query().Get("name")
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("Hello %s!", name)))
}
- Create a file called post.go with the following contents:
package handlers
import (
"encoding/json"
"net/http"
)
// GreetingResponse is the JSON Response that
// GreetingHandler returns
type GreetingResponse struct {
Payload struct {
Greeting string `json:"greeting,omitempty"`
Name string `json:"name,omitempty"`
Error string `json:"error,omitempty"`
} `json:"payload"`
Successful bool `json:"successful"`
}
// GreetingHandler returns a GreetingResponse which either has
// errors or a useful payload
func GreetingHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
var gr GreetingResponse
if err := r.ParseForm(); err != nil {
gr.Payload.Error = "bad request"
if payload, err := json.Marshal(gr); err == nil {
w.Write(payload)
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
}
name := r.FormValue("name")
greeting := r.FormValue("greeting")
w.WriteHeader(http.StatusOK)
gr.Successful = true
gr.Payload.Name = name
gr.Payload.Greeting = greeting
if payload, err := json.Marshal(gr); err == nil {
w.Write(payload)
}
}
- Create a new directory named example and navigate to it.
- Create a file called main.go with the following contents:
package main
import (
"fmt"
"net/http"
"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
$ chapter8/handlers"
)
func main() {
http.HandleFunc("/name", handlers.HelloHandler)
http.HandleFunc("/greeting", handlers.GreetingHandler)
fmt.Println("Listening on port :3333")
err := http.ListenAndServe(":3333", nil)
panic(err)
}
- Run go run main.go.
- You could also run the following command:
$ go build
$ ./example
You should see the following output:
$ go run main.go
Listening on port :3333
- In a separate Terminal, run the following commands:
$ curl "http://localhost:3333/name?name=Reader" -X GET
$ curl "http://localhost:3333/greeting" -X POST -d
'name=Reader;greeting=Goodbye'
You should see the following output:
$ curl "http://localhost:3333/name?name=Reader" -X GET
Hello Reader!
$ curl "http://localhost:3333/greeting" -X POST -d 'name=Reader;greeting=Goodbye'
{"payload":{"greeting":"Goodbye","name":"Reader"},"successful":true}
- The go.mod file may be updated and the go.sum file should now be present in the top-level recipe directory.
- If you copied or wrote your own tests, go up one directory and run go test. Ensure that all tests pass.