How to do it...

The following steps cover the writing and running of your application:

  1. From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter8/validationand navigate to this directory.
  1. Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter8/validation

You should see a file called go.mod that contains the following:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter8/validation    
  1. Copy the tests from ~/projects/go-programming-cookbook-original/chapter8/validation, or use this as an exercise to write some of your own code!
  2. Create a file called controller.go with the following contents:
        package validation

// Controller holds our validation functions
type Controller struct {
ValidatePayload func(p *Payload) error
}

// New initializes a controller with our
// local validation, it can be overwritten
func New() *Controller {
return &Controller{
ValidatePayload: ValidatePayload,
}
}
  1. Create a file called validate.go with the following contents:
        package validation

import "errors"

// Verror is an error that occurs
// during validation, we can
// return this to a user
type Verror struct {
error
}

// Payload is the value we
// process
type Payload struct {
Name string `json:"name"`
Age int `json:"age"`
}

// ValidatePayload is 1 implementation of
// the closure in our controller
func ValidatePayload(p *Payload) error {
if p.Name == "" {
return Verror{errors.New("name is required")}
}

if p.Age <= 0 || p.Age >= 120 {
return Verror{errors.New("age is required and must be a
value greater than 0 and less than 120")}
}
return nil
}
  1. Create a file called process.go with the following contents:
        package validation

import (
"encoding/json"
"fmt"
"net/http"
)

// Process is a handler that validates a post payload
func (c *Controller) Process(w http.ResponseWriter, r
*http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}

decoder := json.NewDecoder(r.Body)
defer r.Body.Close()
var p Payload

if err := decoder.Decode(&p); err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}

if err := c.ValidatePayload(&p); err != nil {
switch err.(type) {
case Verror:
w.WriteHeader(http.StatusBadRequest)
// pass the Verror along
w.Write([]byte(err.Error()))
return
default:
w.WriteHeader(http.StatusInternalServerError)
return
}
}
}
  1. Create a new directory named example and navigate to it.
  2. 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/validation"
)

func main() {
c := validation.New()
http.HandleFunc("/", c.Process)
fmt.Println("Listening on port :3333")
err := http.ListenAndServe(":3333", nil)
panic(err)
}
  1. Run go run main.go.
  2. You could also run the following:
$ go build
$ ./example

You should see the following output:

$ go run main.go
Listening on port :3333
  1. In a separate Terminal, run the following commands:
$ curl "http://localhost:3333/" -X POST -d '{}'
$ curl "http://localhost:3333/" -X POST -d '{"name":"test"}'
$ curl "http://localhost:3333/" -X POST -d '{"name":"test",
"age": 5}' -v

You should see the following output:

$ curl "http://localhost:3333/" -X POST -d '{}'
name is required


$ curl "http://localhost:3333/" -X POST -d '{"name":"test"}'
age is required and must be a value greater than 0 and
less than 120


$ curl "http://localhost:3333/" -X POST -d '{"name":"test",
"age": 5}' -v


<lots of output, should contain a 200 OK status code>
  1. The go.mod file may be updated and the go.sum file should now be present in the top-level recipe directory.
  2. If you copied or wrote your own tests, go up one directory and run go test. Ensure that all tests pass.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.139.50