Home > Software design >  How to validate a text template in golang and matches it with struct?
How to validate a text template in golang and matches it with struct?

Time:08-02

I'm using Golang template package to create a templating and fills the values using struct.

Let's use the example code which can be found on the doc

type Inventory struct {
    Material string
    Count    uint
}

sweaters := Inventory{"wool", 17}
tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
    if err != nil { panic(err) }
err = tmpl.Execute(os.Stdout, sweaters)
    if err != nil { panic(err) }

This is my situation. I received a JSON request from client with the data of the value to fill into the template. Now, this is what I wanna validate. I wanna make sure that the client sends the correct request and that each field in the struct matches with the variable on the template. Like, I wanna make sure that the struct Inventory has Count and Material.

I'm gonna validate it after the request is bind into the struct.

But, there's another thing. I have a bunch of templates. And each template has different fields and variables. So I wanna get the variable definition in the template (like {{.Count}}, counts it, and compares it to the struct.

Is there a way to do this?

CodePudding user response:

Take a look at Go Validator and the examples there.

A basic usage based on your example:

package main

import (
    "fmt"
    "github.com/go-playground/validator/v10"
)

type Inventory struct {
    Material string `validate:"required"`
    Count    int    `validate:"required,min=2"`
}

func main() {
    input := Inventory{
        Material: "",
        Count:    1,
    }

    err := validator.New().Struct(input)  

    // Handle the error ...
    fmt.Printf("% v", err)

    // Proceed processing your data and template...
}

Output will be something like this:

Key: 'Inventory.Material' Error:Field validation for 'Material' failed on the 'required' tag
Key: 'Inventory.Count' Error:Field validation for 'Count' failed on the 'min' tag

You can customize the validation messages and add your own custom validations if you so choose.

Your special case

If the variables in template and struct are widely different you may need to handle each of the field manually.

For example you may parse the template beforehand and count all usages of {{*}} and then build a map based on this - all variables used in template are required I assume.

Then you can compare the map against the input map and check if all fields would be present.

If you want to apply more complex validation rules, you may have to come up with some kind of schema validation and specify with template the valid schema definition.
This library may help you: gojsonschema

  •  Tags:  
  • go
  • Related