D'après ce que j'ai pu découvrir, Huma ne prend malheureusement pas en charge les filtres de requête de tableau comme celui-ci : filters[]=filter1&filters[]=filter2 (sans laisser les crochets de côté, par exemple filter=filter1&filter=filter2). Je suis tombé sur ce problème Github qui donne un exemple de séparation des filtres par virgule https://github.com/danielgtaylor/huma/issues/325, c'est donc ce que nous avons fini par faire : filters=postcode:eq:RM7(EX, créé : gt : 2024-01-01
Contrairement aux paramètres du corps, que l'on peut simplement spécifier en tant que structures et qui sont ensuite à la fois validés et générés dans la documentation, la documentation et la validation des filtres doivent être effectuées séparément.
La documentation peut simplement être ajoutée sous l'attribut description de l'objet Huma.Param (sous Opération) :
Parameters: []*huma.Param{{ Name: "filters", In: "query", Description: "Filter properties by various fields. Separate filters by comma.\n\n" + "Format: field:operator:value\n\n" + "Supported fields:\n" + "- postcode (operator: eq)\n" + "- created (operators: gt, lt, gte, lte)\n", Schema: &huma.Schema{ Type: "string", Items: &huma.Schema{ Type: "string", Pattern: "^[a-zA-Z_]+:(eq|neq|gt|lt|gte|lte):[a-zA-Z0-9-:.]+$", }, Examples: []any{ "postcode:eq:RM7 8EX", "created:gt:2024-01-01", }, }, Required: false, }},
Nous pouvons maintenant définir notre structure PropertyFilterParams pour validation :
type FilterParam struct { Field string Operator string Value interface{} } type PropertyFilterParams struct { Items []FilterParam } func (s *PropertyFilterParams) UnmarshalText(text []byte) error { equalityFields := []string{"postcode"} greaterSmallerFields := []string{} dateFields := []string{"created"} for _, item := range strings.Split(string(text), ",") { filterParam, err := parseAndValidateFilterItem(item, equalityFields, greaterSmallerFields, dateFields) if err != nil { return err } s.Items = append(s.Items, filterParam) } return nil } func (s *PropertyFilterParams) Schema(registry huma.Registry) *huma.Schema { return &huma.Schema{ Type: huma.TypeString, } } func parseAndValidateFilterItem(item string, equalityFields []string, greaterSmallerFields []string, dateFields []string) (FilterParam, error) { parts := strings.SplitN(item, ":", 3) field := parts[0] operator := parts[1] value := parts[2] if contains(equalityFields, field) { if operator != "eq" && operator != "neq" { return FilterParam{}, fmt.Errorf("Unsupported operator %s for field %s. Only 'eq' and 'neq' are supported.", operator, field) } } else if contains(greaterSmallerFields, field) { if !validation.IsValidCompareGreaterSmallerOperator(operator) { return FilterParam{}, fmt.Errorf("Unsupported operator %s for field %s. Supported operators: eq, neq, gt, lt, gte, lte.", operator, field) } } else if contains(dateFields, field) { if !validation.IsValidCompareGreaterSmallerOperator(operator) { return FilterParam{}, fmt.Errorf("Unsupported operator %s for field %s. Supported operators: eq, neq, gt, lt, gte, lte.", operator, field) } if !validation.IsValidDate(value) { return FilterParam{}, fmt.Errorf("Invalid date format: %s. Expected: YYYY-MM-DD", value) } } else { return FilterParam{}, fmt.Errorf("Unsupported filter field: %s", field) } return FilterParam{Field: field, Operator: operator, Value: value}, nil }
J'ai ajouté PropertyFilterParams à la structure PropertyQueryParams :
type PropertyQueryParams struct { PaginationParams Filter PropertyFilterParams `query:"filters" doc:"Filter properties by various fields"` Sort PropertySortParams `query:"sorts" doc:"Sort properties by various fields"` }
Voici à quoi ressemble l'ajout de PropertyQueryParams à la route (notez que le code d'opération lui-même, y compris la description du filtre, se trouve sous getAllPropertyOperation - je n'ai pas collé le code complet pour cela, mais j'espère que vous en comprenez l'essentiel) . Si la validation échoue, elle générera une réponse 422. J'ai également ajouté comment nous pouvons parcourir les valeurs de filtre qui ont été transmises :
huma.Register(api, getAllPropertyOperation(schema, "get-properties", "/properties", []string{"Properties"}), func(ctx context.Context, input *struct { models.Headers models.PropertyQueryParams }) (*models.MultiplePropertyOutput, error) { for _, filter := range input.Filter.Items { fmt.Println(filter) } return mockMultiplePropertyResponse(), err }) }
J'espère que cela aidera quelqu'un. Faites-moi savoir dans les commentaires si vous avez trouvé une meilleure solution.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!