پچھلے حصے نے درخواست پیرامیٹرز کو سیدھے طریقے سے پڑھنے کا طریقہ متعارف کیا۔ اگر ہر پیرامیٹر کو الگ الگ پڑھنا پریشانی دے رہا ہو تو iris فریم ورک بھی پیرامیٹر بائنڈنگ میکینزم فراہم کرتا ہے، جو درخواست پیرامیٹرز کو ایک سٹرکٹ سے بائنڈ کر سکتا ہے، اور فارم پیرامیٹر ویلیڈیشن میکینزم کو بھی سپورٹ کرتا ہے۔

ماڈل بائنڈنگ اور ویلیڈیشن

ریکویسٹ باڈی کو ایک ٹائپ کے ساتھ بائنڈ کرنے کے لئے، ماڈل بائنڈنگ کا استعمال کریں۔ حالیہ میں، ہم 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 کو Content-Type ہیڈر کے بناۓ بائنڈر کا انفار کرنے کی اجازت ہوتی ہے۔ اگر آپ موقعیط ہوں کہ آپ کو کونٹینٹ بائنڈ کرنا ہے، تو آپ مخصوص ReadXXX میتھڈز، جیسے ReadJSON یا ReadProtobuf، کا استعمال کر سکتے ہیں۔

ReadBody(ptr interface{}) error

Aپرغوازی کی ساتھ، Iris ذاتی طور پر دانشمند اور مضمونی ڈیٹا ویلیڈیشن کے ساتھ آتا ہے۔ البتہ، یہ آپ کو ایک ویلیڈیٹر منسلک کرنے کی اجازت دیتا ہے جو ReadJSON، ReadXML وغیرہ جیسی میتھڈز پر خود بخود بلایا جائے گا۔ اس مثال میں، ہم سیکھیں گے کہ گو-پلے-گراؤنڈ/ویلیڈیٹر/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")
}

// صارف صارف کی معلومات شامل ہے۔
type User struct {
    FirstName      string     `json:"fname" validate:"required"` // پہلا نام، ضروری ہے
    LastName       string     `json:"lname" validate:"required"` // آخری نام، ضروری ہے
    Age            uint8      `json:"age" validate:"gte=0,lte=130"` // عمر، صفر اور ایک سو تک کا رینج
    Email          string     `json:"email" validate:"required,email"` // ای میل، ضروری ہے
    FavouriteColor string     `json:"favColor" validate:"hexcolor|rgb|rgba"` // پسندیدہ رنگ، قانونی ہینکس، آر جی بی، یا آر جی بی اے رنگیں ہونی چاہئیں
    Addresses      []*Address `json:"addresses" validate:"required,dive,required"` // پتے کی فہرست، خالی نہیں ہونی چاہئیں اور ہر پتہ ضروری ہے
}

// پتہ صارف کی پتہ معلومات ذخیرہ کرتا ہے۔
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)

            // آپلیکیشن/JSON+مسئلہ جواب کو واپس کریں اور مابقا ہینڈلر کو روکیں
            ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
                Title("تصحیح خطوط").
                Detail("ایک یا ایک سے زیادہ فیلڈز کی تصدیق نہیں ہوئی ہیں").
                Type("/user/validation-errors").
                Key("errors", validationErrors))

            return
        }

        // یہ شاید ایک داخلی JSON خطا ہو، یہاں مزید معلومات فراہم نہیں کی گئی ہے۔
        ctx.StopWithStatus(iris.StatusInternalServerError)
        return
    }

    ctx.JSON(iris.Map{"message": "ٹھیک ہے"})
}

func resolveErrorsDocumentation(ctx iris.Context) {
    ctx.WriteString("اس صفحہ کا استعمال ویب ڈویلپر یا API صارفوں کو تصحیح خطوط کس طرح حل کرنا ہے۔")
}
{
    "title": "تصحیح کی خرابی",
    "detail": "ایک یا ایک سے زیادہ شادی شدہ کمیوں کی تصدیق میں ناکامی",
    "type": "http://localhost:8080/user/validation-errors",
    "status": 400,
    "fields": [
        {
            "tag": "ضروری",
            "namespace": "User.FirstName",
            "kind": "string",
            "type": "string",
            "value": "",
            "param": ""
        },
        {
            "tag": "ضروری",
            "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("شخص: %#+v", person)
    ctx.WriteString("کامیابی")
}

متفرق ڈیٹا کو بائنڈ کرنا

کلائنٹ کی طرف سے بھیجی گئی ڈیٹا کے مواد کے مطابق "ptr" کو درخواست باڈی سے بائنڈ کریں، جیسے کہ JSON، XML، YAML، MessagePack، Protobuf، فارم، اور یوآراق لاگ کے۔

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("شخص: %#+v", person)
    ctx.WriteString("کامیابی")
}

آپ نیچے دیے گئے کمانڈ کا استعمال کرکے ٹیسٹ کرسکتے ہیں:

$ 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("میرے پیرامیٹر: %#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"
}