danielgtaylor / huma

Huma REST/HTTP API Framework for Golang with OpenAPI 3.1
https://huma.rocks/
MIT License
1.95k stars 144 forks source link

Validation for nested to array primitive types. #493

Closed superstas closed 2 months ago

superstas commented 3 months ago

Hi there!

I want to ask about validating primitive types nested in an array.

For example, I've got the following input:

type Input struct {
    Body struct {
        ID  int   `json:"id" required:"true" minimum:"1" maximum:"10"`
        IDs []int `json:"ids" required:"true" minItems:"1" maxItems:"4"`
    }
}

Full code of the example: https://go.dev/play/p/hp1CsyyU6dt

Huma generates the following OAS spec for this type

    InputBody:
      additionalProperties: false
      properties:
        $schema:
          description: A URL to the JSON Schema for this object.
          examples:
            - https://example.com/schemas/InputBody.json
          format: uri
          readOnly: true
          type: string
        id:
          format: int64
          maximum: 10
          minimum: 1
          type: integer
        ids:
          items:
            format: int64
            type: integer
          maxItems: 4
          minItems: 1
          type: array
      required:
        - id
        - ids
      type: object

Screenshot from 2024-07-01 15-52-43

Is there a way to specify validation rules by using struct tags to get the same validation rules for ids as for id?

...
         id:
          format: int64
          maximum: 10
          minimum: 1
          type: integer
        ids:
          items:
            format: int64
            type: integer
            maximum: 10  <-- Added 
            minimum: 1  <-- Added
          maxItems: 4
          minItems: 1
          type: array
...

Screenshot from 2024-07-01 15-51-34

Thank you.

danielgtaylor commented 2 months ago

@superstas thanks for the question! This isn't currently possible. Go doesn't allow tags on slice elements like it does struct fields, however you can wrap the int type and provide the schema as described in https://huma.rocks/features/schema-customization/#field-schema:

type MyItem int

func (i *MyItem) Schema(r huma.Registry) *huma.Schema {
    min := 1.0
    return &huma.Schema{Type: "integer", Format: "int64", Minimum: &min}
}

type DemoResponse struct {
    Body struct {
        IDs   []MyItem `json:"ids" minItems:"2"`
    }
}

Maybe in the future Huma should detect which validation applies to the array vs. the array's items.

superstas commented 2 months ago

Hey @danielgtaylor

Thank you for the reply.

We ended up with a similar workaround.

Maybe in the future Huma should detect which validation applies to the array vs. the array's items.

That would be great. Thank you!