Rumah > pembangunan bahagian belakang > Golang > Menambah parameter pertanyaan penapis dalam Go Huma

Menambah parameter pertanyaan penapis dalam Go Huma

Patricia Arquette
Lepaskan: 2024-12-07 04:38:16
asal
667 orang telah melayarinya

Daripada apa yang saya dapat ketahui, Huma malangnya tidak menyokong penapis pertanyaan tatasusunan seperti ini: filters[]=filter1&filters[]=filter2 (tidak meninggalkan tanda kurung, mis. filter=filter1&filter=filter2). Saya terjumpa isu Github ini yang memberikan contoh pemisahan penapis dengan koma https://github.com/danielgtaylor/huma/issues/325, jadi itulah yang akhirnya kami lakukan: filters=postcode:eq:RM7(EX, dicipta:gt:2024-01-01

Mendokumentasikan penapis

Tidak seperti parameter badan, yang boleh ditentukan hanya sebagai struct dan kemudian kedua-duanya disahkan dan dijana dalam dokumentasi, dokumentasi dan pengesahan untuk penapis perlu dilakukan secara berasingan.

Dokumentasi hanya boleh ditambah di bawah atribut perihalan objek Huma.Param (di bawah Operasi):

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,
        }},
Salin selepas log masuk

Adding filter query parameters in Go Huma

Kami kini boleh mentakrifkan struct PropertyFilterParams kami untuk pengesahan:

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
}
Salin selepas log masuk

Saya menambah PropertyFilterParams pada struct 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"`
}
Salin selepas log masuk

Beginilah rupa menambahkan PropertyQueryParams pada laluan (perhatikan bahawa kod Operasi itu sendiri, termasuk penerangan penapis, berada di bawah getAllPropertyOperation - Saya tidak menampal kod lengkap untuk itu, tetapi mudah-mudahan anda mendapat intipatinya) . Jika pengesahan gagal, ia akan memberikan respons 422. Saya juga menambah cara kita boleh mengulangi nilai penapis yang diluluskan:

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
        })
}
Salin selepas log masuk

Saya harap ini membantu seseorang. Beritahu saya dalam ulasan, jika anda menemui penyelesaian yang lebih baik.

Atas ialah kandungan terperinci Menambah parameter pertanyaan penapis dalam Go Huma. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan