Önceki bölümler, istek parametrelerini doğrudan okumanın yöntemini tanıttı. Her bir parametreyi ayrı ayrı okumak zorluysa, iris çerçevesi ayrıca bir parametre bağlama mekanizması da sağlar, bu mekanizma istek parametrelerini bir yapıya bağlayabilir ve ayrıca bir form parametre doğrulama mekanizmasını da destekler.
Model Bağlama ve Doğrulama
İsteği bir türe bağlamak için model bağlama kullanılır. Şu anda, JSON
, JSONProtobuf
, Protobuf
, MsgPack
, XML
, YAML
ve standart form değerleri (foo=bar&boo=baz) gibi tipleri bağlama desteği sunmaktayız.
// Aşağıda, çeşitli formatlardaki istek parametrelerini bir yapıya bağlamak için işlev tanımlamaları bulunmaktadır
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
kullanırken, Iris, Content-Type başlığına dayalı bağlayıcıyı çıkaracaktır. Bağlamak istediğiniz içeriği kesin olarak biliyorsanız, belirli ReadXXX
yöntemlerini, örneğin ReadJSON
veya ReadProtobuf
kullanabilirsiniz.
ReadBody(ptr interface{}) error
Iris, akıllı yerleşik veri doğrulamayla birlikte gelir. Bununla birlikte, ReadJSON
, ReadXML
vb. gibi yöntemlerde otomatik olarak çağrılacak bir doğrulayıcı eklemenize izin verir. Bu örnekte, isteği doğrulamak için go-playground/validator/v10 kullanımını öğreneceğiz.
Lütfen dikkat edin, bağlanacak tüm alanlara karşılık gelen bağlama etiketlerini ayarlamanız gerekmektedir. Örneğin, JSON'dan bağlarken, json:"alanadı"
şeklinde ayarlayın.
Ayrıca belirli alanları zorunlu alanlar olarak belirtebilirsiniz. Bir alanın binding:"required"
dekorasyonuna sahip olması ve bağlanırken bir değer sağlanmaması durumunda bir hata döndürülecektir.
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("/kullanıcı")
{
userRouter.Get("/doğrulama-hataları", resolveErrorsDocumentation)
userRouter.Post("/", postUser)
}
app.Listen(":8080")
}
// User contains user information.
type User struct {
FirstName string `json:"ad" validate:"required"` // İsim, gerekli
LastName string `json:"soyad" validate:"required"` // Soyisim, gerekli
Age uint8 `json:"yaş" validate:"gte=0,lte=130"` // Yaş, 0 ile 130 arasında bir değer olmalı
Email string `json:"e-posta" validate:"required,email"` // E-posta, gerekli
FavouriteColor string `json:"sevilenRenk" validate:"hexcolor|rgb|rgba"` // Favori renk, geçerli bir onaltılık, RGB veya RGBA renk değeri olmalı
Addresses []*Address `json:"adresler" validate:"required,dive,required"` // Adres listesi, boş olmamalı ve her adres ögesi gerekli
}
// Address stores user address information.
type Address struct {
Street string `json:"sokak" validate:"required"` // Sokak, gerekli
City string `json:"şehir" validate:"required"` // Şehir, gerekli
Planet string `json:"gezegen" validate:"required"` // Gezegen, gerekli
Phone string `json:"telefon" validate:"required"` // Telefon, gerekli
}
type validationError struct {
ActualTag string `json:"etiket"` // Gerçek etiket
Namespace string `json:"adAlanı"` // Ad alanı
Kind string `json:"tür"` // Tür
Type string `json:"tür"` // Tür
Value string `json:"değer"` // Değer
Param string `json:"parametre"` // Parametre
}
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 {
// Hataları ele al, aşağıdaki doğru yolu...
if errs, ok := err.(validator.ValidationErrors); ok {
// Hataları JSON biçiminde paketle, alttaki kütüphane hataları arayüz türünde döndürür.
validationErrors := wrapValidationErrors(errs)
// Bir application/json+problem yanıtı döndür ve sonraki işlemleri durdur
ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
Title("Doğrulama Hataları").
Detail("Bir veya daha fazla alan doğrulamayı geçemedi").
Type("/user/doğrulama-hataları").
Key("hatalar", validationErrors))
return
}
// İçsel bir JSON hatası olabilir, burada daha fazla bilgi sağlanmamıştır.
ctx.StopWithStatus(iris.StatusInternalServerError)
return
}
ctx.JSON(iris.Map{"mesaj": "OK"})
}
func resolveErrorsDocumentation(ctx iris.Context) {
ctx.WriteString("Bu sayfa doğrulama hatalarını web geliştiricilere veya API kullanıcılarına nasıl çözeceklerini açıklamak için kullanılır")
}
{
"fname": "",
"lname": "",
"age": 45,
"email": "[email protected]",
"favColor": "#000",
"addresses": [{
"street": "Eavesdown Docks",
"planet": "Persphone",
"phone": "none",
"city": "Unknown"
}]
}
Örnek Yanıt
{
"title": "Doğrulama Hatası",
"detail": "Bir veya daha fazla alan doğrulamayı geçemedi",
"type": "http://localhost:8080/kullanıcı/doğrulama-hataları",
"status": 400,
"fields": [
{
"tag": "gerekli",
"namespace": "Kullanıcı.Adı",
"kind": "dize",
"type": "dize",
"value": "",
"param": ""
},
{
"tag": "gerekli",
"namespace": "Kullanıcı.Soyadı",
"kind": "dize",
"type": "dize",
"value": "",
"param": ""
}
]
}
URL sorgu parametrelerini bağlama
ReadQuery
yöntemi, sadece sorgu parametrelerini bağlar, istek gövde verilerini bağlamaz. İstek gövde verilerini bağlamak için ReadForm
yöntemini kullanın.
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("Başarılı")
}
Keyfi veri bağlama
İstemci tarafından gönderilen verinin içerik türüne bağlı olarak istek gövdesini "ptr" ile bağlayın, örneğin JSON, XML, YAML, MessagePack, Protobuf, Form ve URL sorgusu.
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("Başarılı")
}
Aşağıdaki komutla test edebilirsiniz:
$ curl -X GET "localhost:8085/testing?name=kataras&address=xyz&birthday=1992-03-15&createTime=1562400033000000123&unixTime=1562400033"
URL yol parametrelerini bağlama
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")
}
İstek
$ curl -v http://localhost:8080/kataras/27/iris/web/framework
Başlık istek parametrelerini bağlama
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")
}
İstek
curl -H "x-request-id:373713f0-6b4b-42ea-ab9f-e2e04bc38e73" -H "authentication: Bearer my-token" \
http://localhost:8080
Yanıt
{
"RequestID": "373713f0-6b4b-42ea-ab9f-e2e04bc38e73",
"Authentication": "Bearer my-token"
}