如何在Golang中验证文本模板并将其与结构体匹配?

huangapple go评论74阅读模式
英文:

How to validate a text template in golang and matches it with struct?

问题

我正在使用Golang的模板包来创建模板,并使用结构体填充值。

让我们使用文档中可以找到的示例代码:

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) }

这是我的情况。我从客户端收到一个JSON请求,其中包含要填充到模板中的值的数据。现在,我想要验证的是,我想确保客户端发送了正确的请求,并且结构体中的每个字段与模板中的变量匹配。比如,我想要确保结构体InventoryCountMaterial字段。

我会在请求绑定到结构体之后进行验证。

但是,还有另一件事。我有一堆模板。每个模板都有不同的字段和变量。所以我想获取模板中的变量定义(比如{{.Count}}),并对其进行计数,然后与结构体进行比较。

有办法做到这一点吗?

英文:

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?

答案1

得分: 1

请看一下Go Validator和其中的示例。

根据你的示例,以下是基本用法:

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)

	// 处理错误...
	fmt.Printf("%+v", err)

	// 继续处理数据和模板...
}

输出结果将类似于:

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

你可以自定义验证消息并添加自己的自定义验证规则,如果需要的话。

特殊情况

如果模板和结构体中的变量差异很大,你可能需要手动处理每个字段。

例如,你可以预先解析模板并计算{{*}}的使用次数,然后基于此构建一个映射 - 假设模板中使用的所有变量都是必需的。

然后,你可以将该映射与输入映射进行比较,并检查是否所有字段都存在。

如果你想应用更复杂的验证规则,可能需要设计一种模式验证,并在模板中指定有效的模式定义。

这个库可能对你有帮助:gojsonschema

英文:

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

huangapple
  • 本文由 发表于 2022年7月28日 14:41:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/73148316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定