पिछले खंडों में प्राथमिकता प्राप्त करने के तरीके को प्रस्तुत किया गया था। यदि प्रत्येक पैरामीटर को अलग-अलग पढ़ना जटिल है, तो आईरिस फ्रेमवर्क एक पैरामीटर बाइंडिंग तंत्र भी प्रदान करता है, जो एक स्ट्रक्ट को रिक्वेस्ट पैरामीटर्स से बाइंड कर सकता है, और एक फॉर्म पैरामीटर मान्यीकरण तंत्र को भी समर्थित करता है।

मॉडल बाइंडिंग और वैधीकरण

अनुरोध बॉडी को एक प्रकार से जोड़ने के लिए, मॉडल बाइंडिंग का उपयोग करें। वर्तमान में, हम JSON, JSONProtobuf, Protobuf, MsgPack, XML, YAML, और मानक फॉर्म मान्यताएँ (foo=bar&boo=baz) जैसे प्रकारों को जोड़ने का समर्थन करते हैं।

// नीचे विभिन्न प्रारूपों के अनुरोध पैरामीटरों को एक संरचना से जोड़ने के लिए फ़ंक्शन परिभाषाएँ हैं
ReadJSON(outPtr interface{}) error
ReadJSONProtobuf(ptr proto.Message, opts ...ProtoUnmarshalOptions) error
ReadProtobuf(ptr proto.Message) error
ReadMsgPack(ptr interface{}) error
ReadXML(outPtr interface{}) error
ReadYAML(outPtr interface{}) error
ReadForm(formObject interface{}) error
ReadQuery(ptr interface{}) error

ReadBody का उपयोग करते समय, Iris कॉन्टेंट-टाइप हेडर के आधार पर बाइंडर को स्वत: संकेत करेगा। यदि आप जोड़ना चाहते हैं, तो आप विशिष्ट ReadXXX मेथड का उपयोग कर सकते हैं, जैसे कि ReadJSON या ReadProtobuf

ReadBody(ptr interface{}) error

Iris में बुद्धिमान आवंटित डेटा वैधीकरण के साथ आता है। हालांकि, यह आपको एक वैधीकरणकर्ता संलग्न करने की अनुमति देता है जो मेथड्स जैसे कि ReadJSON, ReadXML, आदि पर स्वचालित रूप से कॉल किया जाएगा। इस उदाहरण में, हमें सीखना होगा कि रिक्ति को वैधीकृत करने के लिए go-playground/validator/v10 का उपयोग कैसे करें।

कृपया ध्यान दें कि आपको जोड़े जाने वाले सभी क्षेत्रों पर संबंधित जोड़ने के टैग सेट करने की आवश्यकता होगी। उदाहरण के लिए, जब JSON से बाइंड किया जाता है, तो json:"fieldname" सेट करें।

आप निश्चित क्षेत्रों को अनिवार्य क्षेत्रों के रूप में भी निर्दिष्ट कर सकते हैं। यदि एक क्षेत्र में binding:"required" सजावट है और जोड़ने के दौरान कोई मान नहीं दिया जाता है, तो एक त्रुटि दी जाएगी।

package main

import (
    "fmt"

    "github.com/kataras/iris/v12"
    "github.com/go-playground/validator/v10"
)

func main() {
    app := iris.New()
    app.Validator = validator.New()

    userRouter := app.Party("/user")
    {
        userRouter.Get("/validation-errors", resolveErrorsDocumentation)
        userRouter.Post("/", postUser)
    }
    app.Listen(":8080")
}

// User contains user information.
type User struct {
    FirstName      string     `json:"fname" validate:"required"` // पहला नाम, आवश्यक
    LastName       string     `json:"lname" validate:"required"` // अंतिम नाम, आवश्यक
    Age            uint8      `json:"age" validate:"gte=0,lte=130"` // आयु, 0 और 130 के बीच होनी चाहिए
    Email          string     `json:"email" validate:"required,email"` // ईमेल, आवश्यक
    FavouriteColor string     `json:"favColor" validate:"hexcolor|rgb|rgba"` // पसंदीदा रंग, वैध 16-रूपीया, आरजीबी या आरजीबीए रंग मान होना चाहिए
    Addresses      []*Address `json:"addresses" validate:"required,dive,required"` // पता सूची, खाली नहीं होना चाहिए और प्रत्येक पता आइटम आवश्यक है
}

// Address stores user address information.
type Address struct {
    Street string `json:"street" validate:"required"` // सड़क, आवश्यक
    City   string `json:"city" validate:"required"` // शहर, आवश्यक
    Planet string `json:"planet" validate:"required"` // ग्रह, आवश्यक
    Phone  string `json:"phone" validate:"required"` // फ़ोन, आवश्यक
}

type validationError struct {
    ActualTag string `json:"tag"` // वास्तविक टैग
    Namespace string `json:"namespace"` // नेमस्पेस
    Kind      string `json:"kind"` // प्रकार
    Type      string `json:"type"` // प्रकार
    Value     string `json:"value"` // मान
    Param     string `json:"param"` // पैरामीटर
}

func wrapValidationErrors(errs validator.ValidationErrors) []validationError {
    validationErrors := make([]validationError, 0, len(errs))
    for _, validationErr := range errs {
        validationErrors = append(validationErrors, validationError{
            ActualTag: validationErr.ActualTag(),
            Namespace: validationErr.Namespace(),
            Kind:      validationErr.Kind().String(),
            Type:      validationErr.Type().String(),
            Value:     fmt.Sprintf("%v", validationErr.Value()),
            Param:     validationErr.Param(),
        })
    }

    return validationErrors
}

func postUser(ctx iris.Context) {
    var user User
    err := ctx.ReadJSON(&user)
    if err != nil {
        // त्रुटियों का संबंध निकालें, निम्नलिखित सही तरीका है...
        if errs, ok := err.(validator.ValidationErrors); ok {
            // त्रुटियों को JSON प्रारूप में अंकित करें, अंतर्निहित पुस्तकालय त्रुटियों को त्रुटि प्रकार की प्रकृति की त्रुटियों को वापस देता है।
            validationErrors := wrapValidationErrors(errs)
            
            // एक आवेदन/ जेसोन + समस्या प्रतिसाद दर्शाएं और पश्चात पूर्व संग्रहों को न करने के लिए बंद करें
            ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
                Title("त्रुटि सत्यापन").
                Detail("एक या एक से अधिक क्षेत्रों में सत्यापन नहीं हुआ").
                Type("/user/validation-errors").
                Key("त्रुटि", validationErrors))

            return
        }

        // इसमें आंतरिक JSON त्रुटि हो सकती है, यहां और कोई सूचना नहीं दी गई है।
        ctx.StopWithStatus(iris.StatusInternalServerError)
        return
    }

    ctx.JSON(iris.Map{"message": "ठीक है"})
}

func resolveErrorsDocumentation(ctx iris.Context) {
    ctx.WriteString("यह पृष्ठ यह स्पष्ट करने के लिए प्रयोग किया जाता है कि वेब डेवलपर्स या एपीआई उपयोक्ताओं को त्रुटि सत्यापन को कैसे सुलझाना है")
}

नमूना अनुरोध

{
    "fname": "",
    "lname": "",
    "age": 45,
    "email": "[email protected]",
    "favColor": "#000",
    "addresses": [{
        "street": "ईव्सडाउन डॉक्स",
        "planet": "पर्सोफोन",
        "phone": "कोई नहीं",
        "city": "अज्ञात"
    }]
}

नमूना प्रतिक्रिया

{
    "title": "सत्यापन त्रुटि",
    "detail": "एक या एक से अधिक फ़ील्डों को सत्यापन में विफलता हुई",
    "type": "http://localhost:8080/user/validation-errors",
    "status": 400,
    "fields": [
        {
            "tag": "required",
            "namespace": "User.FirstName",
            "kind": "string",
            "type": "string",
            "value": "",
            "param": ""
        },
        {
            "tag": "required",
            "namespace": "User.LastName",
            "kind": "string",
            "type": "string",
            "value": "",
            "param": ""
        }
    ]
}

URL प्रश्न पैरामीटर बाइंडिंग

ReadQuery मेथड केवल प्रश्न पैरामीटर को बाइंड करता है, न कि अनुरोध बॉडी डेटा। "ReadForm" का उपयोग करके अनुरोध बॉडी डेटा को बाइंड करें।

package main

import "github.com/kataras/iris/v12"

type Person struct {
    Name    string `url:"name,required"`
    Address string `url:"address"`
}

func main() {
    app := iris.Default()
    app.Any("/", index)
    app.Listen(":8080")
}

func index(ctx iris.Context) {
    var person Person
    if err := ctx.ReadQuery(&person); err != nil {
        ctx.StopWithError(iris.StatusBadRequest, err)
        return
    }

    ctx.Application().Logger().Infof("Person: %#+v", person)
    ctx.WriteString("Success")
}

अर्बित्रेरी डेटा को बाइंड करना

अनुरोध बॉडी को "ptr" को तालिका की सामग्री के आधार पर बाइंड करें, जैसे कि क्लाइंट द्वारा भेजी गई डेटा के संदर्भ टाइप, जैसे JSON, XML, YAML, MessagePack, Protobuf, फॉर्म, और URL प्रश्न।

package main

import (
    "time"
    "github.com/kataras/iris/v12"
)

type Person struct {
    Name       string    `form:"name" json:"name" url:"name" msgpack:"name"`
    Address    string    `form:"address" json:"address" url:"address" msgpack:"address"`
    Birthday   time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1" json:"birthday" url:"birthday" msgpack:"birthday"`
    CreateTime time.Time `form:"createTime" time_format:"unixNano" json:"create_time" url:"create_time" msgpack:"createTime"`
    UnixTime   time.Time `form:"unixTime" time_format:"unix" json:"unix_time" url:"unix_time" msgpack:"unixTime"`
}

func main() {
    app := iris.Default()
    app.Any("/", index)
    app.Listen(":8080")
}

func index(ctx iris.Context) {
    var person Person
    if err := ctx.ReadBody(&person); err != nil {
        ctx.StopWithError(iris.StatusBadRequest, err)
        return
    }

    ctx.Application().Logger().Infof("Person: %#+v", person)
    ctx.WriteString("Success")
}

आप निम्नलिखित कमांड के साथ परीक्षण कर सकते हैं:

$ curl -X GET "localhost:8085/testing?name=kataras&address=xyz&birthday=1992-03-15&createTime=1562400033000000123&unixTime=1562400033"

URL पथ पैरामीटर बाइंडिंग

package main

import "github.com/kataras/iris/v12"

type myParams struct {
    Name string   `param:"name"`
    Age  int      `param:"age"`
    Tail []string `param:"tail"`
}

func main() {
    app := iris.Default()
    app.Get("/{name}/{age:int}/{tail:path}", func(ctx iris.Context) {
        var p myParams
        if err := ctx.ReadParams(&p); err != nil {
            ctx.StopWithError(iris.StatusInternalServerError, err)
            return
        }

        ctx.Writef("myParams: %#v", p)
    })
    app.Listen(":8088")
}

अनुरोध

$ curl -v http://localhost:8080/kataras/27/iris/web/framework

हेडर अनुरोध पैरामीटर बाइंडिंग

package main

import "github.com/kataras/iris/v12"

type myHeaders struct {
    RequestID      string `header:"X-Request-Id,required"`
    Authentication string `header:"Authentication,required"`
}

func main() {
    app := iris.Default()
    r.GET("/", func(ctx iris.Context) {
        var hs myHeaders
        if err := ctx.ReadHeaders(&hs); err != nil {
            ctx.StopWithError(iris.StatusInternalServerError, err)
            return
        }

        ctx.JSON(hs)
    })
    
    app.Listen(":8080")
}

अनुरोध

curl -H "x-request-id:373713f0-6b4b-42ea-ab9f-e2e04bc38e73" -H "authentication: Bearer my-token" \
http://localhost:8080

प्रतिक्रिया

{
  "RequestID": "373713f0-6b4b-42ea-ab9f-e2e04bc38e73",
  "Authentication": "Bearer my-token"
}