Skip to content

Add custom struct tags to params structs  #2039

Open
@timrabl

Description

@timrabl

What do you want to change?

Hello,
first of all thank you for the brilliant library.

As already mentioned in Issue #534, the feature of custom struct tags was implemented with PR #1569.
However, I noticed that the custom struct tags are only added to the database table structs. But not to the their corresponding parameter structs.

In my opinion, this would also be quite helpful and should not cause more problems than the struct tags of the database types, or tables, at least in terms of compatibility.

Currently I am facing the problem to validate user payloads of a REST API in GoLang.
For this I use among others the libraries: sqlc, gofiber, go-playground/validator/v10.

I noticed the whole thing after I wanted to validate payload data to create a user.
Some project snippets for reference:

version: "2"

sql:
  - engine: "postgresql"
    queries: "db/sqlc/"
    schema: "db/migrations/"
    gen:
      go:
        package: "db"
        out: "internal/db"
        emit_json_tags: true
        emit_empty_slices: true
        emit_db_tags: true
        overrides:
          - column: users.first_name
            go_struct_tag: 'validate:"required"'
          - column: users.flast_name
            go_struct_tag: 'validate:"required"'
          - column: users.email
            go_struct_tag: 'validate:"required,email"'
          - column: users.organizational_unit
            go_struct_tag: 'validate:"required"'
          - column: users.name
            go_struct_tag: 'validate:"required"'
// db.go
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.16.0
type User struct {
	ID                 int32     `db:"id" json:"id"`
	FirstName          string    `db:"first_name" json:"first_name" validate:"required"`
	LastName           string    `db:"last_name" json:"last_name"`
	OrganizationalUnit string    `db:"organizational_unit" json:"organizational_unit" validate:"required"`
	Name               string    `db:"name" json:"name" validate:"required"`
	Email              string    `db:"email" json:"email" validate:"required,email"`
	CreatedAt          time.Time `db:"created_at" json:"created_at"`
	ChangedAt          time.Time `db:"changed_at" json:"changed_at"`
}
// query.sql.go
// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.16.0
// source: query.sql
type UpdateUserParams struct {
	ID                 int32  `db:"id" json:"id"`
	FirstName          string `db:"first_name" json:"first_name"`
	LastName           string `db:"last_name" json:"last_name"`
	OrganizationalUnit string `db:"organizational_unit" json:"organizational_unit"`
	Name               string `db:"name" json:"name"`
	Email              string `db:"email" json:"email"`
}
import (
    "github.com/gofiber/fiber/v2"
    "github.com/go-playground/validator/v10"
    "example.org/internal/database"
    "example.org/internal/db" // sqlc generated package
)

var (
    validate = validator.New()
)

func ValidateStruct(model interface{}) []*ErrorResponse {

	var errors []*ErrorResponse
	err := validate.Struct(model)
	if err != nil {
		for _, err := range err.(validator.ValidationErrors) {
			var element ErrorResponse
			element.FailedField = err.StructNamespace()
			element.Tag = err.Tag()
			element.Value = err.Param()
			errors = append(errors, &element)
		}
	}
	return errors
}

func CreateUser(c *fiber.Ctx) error {
	// user struct contains struct tags for "github.com/go-playground/validator/v10" defined in sqlc.yaml
	userPayload := &db.User{}

	err := c.BodyParser(&userPayload)
	if err != nil {
		return MessageBadRequest(c, "failure while binding payload data to structured data")
	}

	errors := ValidateStruct(*userPayload)
	if errors != nil {
		return MessageBadRequest(c, errors)
	}

	queries := database.GetQueries()
	ctx, cancel := database.NewContext()

	defer cancel()

	// CreateUserParams is missing custom struct tags for "github.com/go-playground/validator/v10" defined in sqlc.yaml
	insertedUser, err := queries.CreateUser(ctx, db.CreateUserParams{
		// ...
	})
	if err != nil {
		return err
	}

	return MessageOK(c, insertedUser)
}

What database engines need to be changed?

PostgreSQL, MySQL

What programming language backends need to be changed?

Go, Python, Kotlin

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions