I am using SQLC to generate structures based on my schema and Gin for the web API.
After viewing this topic here: Golang how to use Validator with SqlC, I noticed the answer specifically says:
I wasn't able to change the Param structs but I guess using the table main struct use the validation.
This is exactly the behavior I am after. I noticed that if I have a query that uses a subset of a given table, e.g.:
-- name: CreateUserBasic :one
INSERT INTO users (
username, email, phone
) VALUES (
$1, $2, $3
) RETURNING *;
It yields a structure as follows:
type CreateUserBasicParams struct {
Username string `json:"username"`
Email string `json:"email"`
Phone pgtype.Text `json:"phone"`
}
In my case, I even included the overrides for adding the "required" tag:
version: 2
sql:
- engine: "postgresql"
schema: [
...
]
queries: [
...
]
strict_function_checks: true
gen:
go:
emit_json_tags: true
sql_package: "pgx/v5"
package: "hmdb"
out: "hmdb"
overrides:
- db_type: users.username
go_struct_tag: validate:"required"
But this only modifies the table struct, not any of the param structs:
type User struct {
ID pgtype.UUID `json:"id"`
Email string `json:"email"`
Phone pgtype.Text `json:"phone"`
Username string `json:"username"`
Password pgtype.Text `json:"password"`
MFAToken pgtype.Text `json:"mfatoken"`
ActivationID pgtype.UUID `json:"activation_id"`
ActivationCode string `json:"activation_code"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
ActivatedAt pgtype.Timestamptz `json:"activated_at"`
Active bool `json:"active"`
}
Using Gin, I want to invoke the CreateUserBasic
with the received data and JSON can be directly Unmashall-ed into the CreateUserBasicParams
structure, but unfortunately without the decorators on the params structure, missing fields are permitted during parsing and it seems I will need to re-create a new structure with a nearly identical layout to the CreateUserBasicParams
struct, only with the proper tags:
func (c *Controller) Register(ctx *gin.Context) {
var params hmdb.CreateUserBasicParams
if err := ctx.ShouldBindWith(¶ms, binding.JSON); err != nil {
ctx.AbortWithError(http.StatusBadRequest, err)
}
log.Printf("Parameters:\n%+v", params)
q := hmdb.New(c.DBPool)
u, err := q.CreateUserBasic(ctx, params)
if err != nil {
ctx.AbortWithError(http.StatusBadRequest, err)
}
log.Printf("New User:\n%+v", u)
ctx.JSON(http.StatusOK, gin.H{
"message": "Good!",
})
}
How can I best apply arbitrary validation to the SQLC-generated "Params" structures without re-creating the structure or modifying the tags?
As you are using per-column overrides, the indentation level for "overrides" should match the version line in the yaml file. For example:
Documented here - https://docs.sqlc.dev/en/stable/reference/config.html?highlight=override#per-column-type-overrides