ホームページ >バックエンド開発 >Golang >Go Huma でのフィルター クエリ パラメーターの追加

Go Huma でのフィルター クエリ パラメーターの追加

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-07 04:38:16686ブラウズ

私が調べたところによると、Huma は残念ながら次のような配列クエリ フィルターをサポートしていません: filters[]=filter1&filters[]=filter2 (括弧も省略しません。例: filter=filter1&filter=filter2)。フィルターをカンマで区切る例を示す Github の issue https://github.com/danielgtaylor/huma/issues/325 を見つけたので、最終的には次のようになりました。 filters=postcode:eq:RM7(EX,作成日:gt:2024-01-01

フィルタの文書化

ボディパラメータは構造体として指定するだけで検証され、ドキュメント内で生成されますが、フィルタのドキュメント化と検証は個別に行う必要があります。

ドキュメントは、Huma.Param オブジェクト (Operation の下) の description 属性の下に簡単に追加できます。

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

Adding filter query parameters in Go Huma

これで、検証用に PropertyFilterParams 構造体を定義できるようになりました。

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
}

PropertyQueryParams 構造体に PropertyFilterParams を追加しました。

type PropertyQueryParams struct {
    PaginationParams
    Filter PropertyFilterParams `query:"filters" doc:"Filter properties by various fields"`
    Sort   PropertySortParams   `query:"sorts" doc:"Sort properties by various fields"`
}

これは、PropertyQueryParams をルートに追加する様子です (フィルターの説明を含むオペレーション コード自体は getAllPropertyOperation の下にあることに注意してください。完全なコードは貼り付けていませんが、要点は理解していただければ幸いです) 。検証が失敗した場合は、422 応答がスローされます。また、渡されたフィルター値をループする方法も追加しました:

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

これが誰かのお役に立てば幸いです。より良い解決策を見つけた場合は、コメントでお知らせください。

以上がGo Huma でのフィルター クエリ パラメーターの追加の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。