mirror of
https://github.com/kataras/iris.git
synced 2026-01-22 19:36:00 +00:00
reorganization of _examples and add some new examples such as iris+groupcache+mysql+docker
Former-commit-id: ed635ee95de7160cde11eaabc0c1dcb0e460a620
This commit is contained in:
58
_examples/request-body/read-body/main.go
Normal file
58
_examples/request-body/read-body/main.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
// See main_test.go for usage.
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
// To automatically decompress using gzip:
|
||||
// app.Use(iris.GzipReader)
|
||||
|
||||
app.Use(setAllowedResponses)
|
||||
|
||||
app.Post("/", readBody)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
type payload struct {
|
||||
Message string `json:"message" xml:"message" msgpack:"message" yaml:"Message" url:"message" form:"message"`
|
||||
}
|
||||
|
||||
func readBody(ctx iris.Context) {
|
||||
var p payload
|
||||
|
||||
// Bind request body to "p" depending on the content-type that client sends the data,
|
||||
// e.g. JSON, XML, YAML, MessagePack, Form, URL Query.
|
||||
err := ctx.ReadBody(&p)
|
||||
if err != nil {
|
||||
ctx.StopWithProblem(iris.StatusBadRequest,
|
||||
iris.NewProblem().Title("Parser issue").Detail(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// For the sake of the example, log the received payload.
|
||||
ctx.Application().Logger().Infof("Received: %#+v", p)
|
||||
|
||||
// Send back the payload depending on the accept content type and accept-encoding of the client,
|
||||
// e.g. JSON, XML and so on.
|
||||
ctx.Negotiate(p)
|
||||
}
|
||||
|
||||
func setAllowedResponses(ctx iris.Context) {
|
||||
// Indicate that the Server can send JSON, XML, YAML and MessagePack for this request.
|
||||
ctx.Negotiation().JSON().XML().YAML().MsgPack()
|
||||
// Add more, allowed by the server format of responses, mime types here...
|
||||
|
||||
// If client is missing an "Accept: " header then default it to JSON.
|
||||
ctx.Negotiation().Accept.JSON()
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
53
_examples/request-body/read-body/main_test.go
Normal file
53
_examples/request-body/read-body/main_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestReadBodyAndNegotiate(t *testing.T) {
|
||||
app := newApp()
|
||||
|
||||
e := httptest.New(t, app)
|
||||
|
||||
var (
|
||||
expectedPayload = payload{Message: "a message"}
|
||||
expectedMsgPackPayload = "\x81\xa7message\xa9a message"
|
||||
expectedXMLPayload = `<payload>
|
||||
<message>a message</message>
|
||||
</payload>
|
||||
`
|
||||
expectedYAMLPayload = "Message: a message\n"
|
||||
)
|
||||
|
||||
// Test send JSON and receive JSON.
|
||||
e.POST("/").WithJSON(expectedPayload).Expect().Status(httptest.StatusOK).
|
||||
JSON().Equal(expectedPayload)
|
||||
|
||||
// Test send Form and receive XML.
|
||||
e.POST("/").WithForm(expectedPayload).
|
||||
WithHeader("Accept", "application/xml").
|
||||
Expect().Status(httptest.StatusOK).
|
||||
Body().Equal(expectedXMLPayload)
|
||||
|
||||
// Test send URL Query and receive MessagePack.
|
||||
e.POST("/").WithQuery("message", expectedPayload.Message).
|
||||
WithHeader("Accept", "application/msgpack").
|
||||
Expect().Status(httptest.StatusOK).ContentType("application/msgpack").
|
||||
Body().Equal(expectedMsgPackPayload)
|
||||
|
||||
// Test send MessagePack and receive MessagePack.
|
||||
e.POST("/").WithBytes([]byte(expectedMsgPackPayload)).
|
||||
WithHeader("Content-Type", "application/msgpack").
|
||||
WithHeader("Accept", "application/msgpack").
|
||||
Expect().Status(httptest.StatusOK).
|
||||
ContentType("application/msgpack").Body().Equal(expectedMsgPackPayload)
|
||||
|
||||
// Test send YAML and receive YAML.
|
||||
e.POST("/").WithBytes([]byte(expectedYAMLPayload)).
|
||||
WithHeader("Content-Type", "application/x-yaml").
|
||||
WithHeader("Accept", "application/x-yaml").
|
||||
Expect().Status(httptest.StatusOK).
|
||||
ContentType("application/x-yaml").Body().Equal(expectedYAMLPayload)
|
||||
}
|
||||
64
_examples/request-body/read-custom-per-type/main.go
Normal file
64
_examples/request-body/read-custom-per-type/main.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// use Postman or whatever to do a POST request
|
||||
// (however you are always free to use app.Get and GET http method requests to read body of course)
|
||||
// to the http://localhost:8080 with RAW BODY:
|
||||
/*
|
||||
addr: localhost:8080
|
||||
serverName: Iris
|
||||
*/
|
||||
//
|
||||
// The response should be:
|
||||
// Received: main.config{Addr:"localhost:8080", ServerName:"Iris"}
|
||||
app.Listen(":8080", iris.WithOptimizations)
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.Post("/", handler)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// simple yaml stuff, read more at https://github.com/go-yaml/yaml
|
||||
type config struct {
|
||||
Addr string `yaml:"addr"`
|
||||
ServerName string `yaml:"serverName"`
|
||||
}
|
||||
|
||||
// Decode implements the `kataras/iris/context#BodyDecoder` optional interface
|
||||
// that any go type can implement in order to be self-decoded when reading the request's body.
|
||||
func (c *config) Decode(body []byte) error {
|
||||
return yaml.Unmarshal(body, c)
|
||||
}
|
||||
|
||||
func handler(ctx iris.Context) {
|
||||
var c config
|
||||
|
||||
//
|
||||
// Note:
|
||||
// second parameter is nil because our &c implements the `context#BodyDecoder`
|
||||
// which has a priority over the context#Unmarshaler (which can be a more global option for reading request's body)
|
||||
// see the `request-body/read-custom-via-unmarshaler/main.go` example to learn how to use the context#Unmarshaler too.
|
||||
//
|
||||
// Note 2:
|
||||
// If you need to read the body again for any reason
|
||||
// you should disable the body consumption via `app.Run(..., iris.WithoutBodyConsumptionOnUnmarshal)`.
|
||||
//
|
||||
|
||||
if err := ctx.UnmarshalBody(&c, nil); err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Received: %#+v", c)
|
||||
}
|
||||
17
_examples/request-body/read-custom-per-type/main_test.go
Normal file
17
_examples/request-body/read-custom-per-type/main_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestReadCustomPerType(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app)
|
||||
|
||||
expectedResponse := `Received: main.config{Addr:"localhost:8080", ServerName:"Iris"}`
|
||||
|
||||
e.POST("/").WithText("addr: localhost:8080\nserverName: Iris").Expect().
|
||||
Status(httptest.StatusOK).Body().Equal(expectedResponse)
|
||||
}
|
||||
72
_examples/request-body/read-custom-via-unmarshaler/main.go
Normal file
72
_examples/request-body/read-custom-via-unmarshaler/main.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// use Postman or whatever to do a POST request
|
||||
// (however you are always free to use app.Get and GET http method requests to read body of course)
|
||||
// to the http://localhost:8080 with RAW BODY:
|
||||
/*
|
||||
addr: localhost:8080
|
||||
serverName: Iris
|
||||
*/
|
||||
//
|
||||
// The response should be:
|
||||
// Received: main.config{Addr:"localhost:8080", ServerName:"Iris"}
|
||||
app.Listen(":8080", iris.WithOptimizations)
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.Post("/", handler)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// simple yaml stuff, read more at https://github.com/go-yaml/yaml
|
||||
type config struct {
|
||||
Addr string `yaml:"addr"`
|
||||
ServerName string `yaml:"serverName"`
|
||||
}
|
||||
|
||||
/*
|
||||
type myBodyDecoder struct{}
|
||||
|
||||
var DefaultBodyDecoder = myBodyDecoder{}
|
||||
|
||||
// Implements the `kataras/iris/context#Unmarshaler` but at our example
|
||||
// we will use the simplest `context#UnmarshalerFunc` to pass just the yaml.Unmarshal.
|
||||
//
|
||||
// Can be used as: ctx.UnmarshalBody(&c, DefaultBodyDecoder)
|
||||
func (r *myBodyDecoder) Unmarshal(data []byte, outPtr interface{}) error {
|
||||
return yaml.Unmarshal(data, outPtr)
|
||||
}
|
||||
*/
|
||||
|
||||
func handler(ctx iris.Context) {
|
||||
var c config
|
||||
|
||||
//
|
||||
// Note:
|
||||
// yaml.Unmarshal already implements the `context#Unmarshaler`
|
||||
// so we can use it directly, like the json.Unmarshal(ctx.ReadJSON), xml.Unmarshal(ctx.ReadXML)
|
||||
// and every library which follows the best practises and is aligned with the Go standards.
|
||||
//
|
||||
// Note 2:
|
||||
// If you need to read the body again for any reason
|
||||
// you should disable the body consumption via `app.Run(..., iris.WithoutBodyConsumptionOnUnmarshal)`.
|
||||
//
|
||||
|
||||
if err := ctx.UnmarshalBody(&c, iris.UnmarshalerFunc(yaml.Unmarshal)); err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Received: %#+v", c)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestReadCustomViaUnmarshaler(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app)
|
||||
|
||||
expectedResponse := `Received: main.config{Addr:"localhost:8080", ServerName:"Iris"}`
|
||||
|
||||
e.POST("/").WithText("addr: localhost:8080\nserverName: Iris").Expect().
|
||||
Status(httptest.StatusOK).Body().Equal(expectedResponse)
|
||||
}
|
||||
44
_examples/request-body/read-form/main.go
Normal file
44
_examples/request-body/read-form/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// package main contains an example on how to use the ReadForm, but with the same way you can do the ReadJSON & ReadJSON
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
type Visitor struct {
|
||||
Username string
|
||||
Mail string
|
||||
Data []string `form:"mydata"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
// set the view html template engine
|
||||
app.RegisterView(iris.HTML("./templates", ".html").Reload(true))
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
if err := ctx.View("form.html"); err != nil {
|
||||
ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
app.Post("/form_action", func(ctx iris.Context) {
|
||||
visitor := Visitor{}
|
||||
err := ctx.ReadForm(&visitor)
|
||||
if err != nil && !iris.IsErrPath(err) /* see: https://github.com/kataras/iris/issues/1157 */ {
|
||||
ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Visitor: %#v", visitor)
|
||||
})
|
||||
|
||||
app.Post("/post_value", func(ctx iris.Context) {
|
||||
username := ctx.PostValueDefault("Username", "iris")
|
||||
ctx.Writef("Username: %s", username)
|
||||
})
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
22
_examples/request-body/read-form/templates/form.html
Normal file
22
_examples/request-body/read-form/templates/form.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<form action="/form_action" method="post">
|
||||
Username: <input type="text" name="Username" /> <br />
|
||||
Mail: <input type="text" name="Mail" /> <br />
|
||||
Select one or more: <br/>
|
||||
<select multiple="multiple" name="mydata">
|
||||
<option value='one'>One</option>
|
||||
<option value='two'>Two</option>
|
||||
<option value='three'>Three</option>
|
||||
<option value='four'>Four</option>
|
||||
</select>
|
||||
|
||||
<hr />
|
||||
<input type="submit" value="Send data" />
|
||||
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
44
_examples/request-body/read-gzip/main.go
Normal file
44
_examples/request-body/read-gzip/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
app.Logger().SetLevel("debug")
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
type payload struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
|
||||
// GzipReader is a middleware which enables gzip decompression,
|
||||
// when client sends gzip compressed data.
|
||||
//
|
||||
// A shortcut of:
|
||||
// func(ctx iris.Context) {
|
||||
// ctx.GzipReader(true)
|
||||
// ctx.Next()
|
||||
// }
|
||||
app.Use(iris.GzipReader)
|
||||
|
||||
app.Post("/", func(ctx iris.Context) {
|
||||
// Bind incoming gzip compressed JSON to "p".
|
||||
var p payload
|
||||
if err := ctx.ReadJSON(&p); err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Send back the message as plain text.
|
||||
ctx.WriteString(p.Message)
|
||||
})
|
||||
|
||||
return app
|
||||
}
|
||||
38
_examples/request-body/read-gzip/main_test.go
Normal file
38
_examples/request-body/read-gzip/main_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestGzipReader(t *testing.T) {
|
||||
app := newApp()
|
||||
|
||||
expected := payload{Message: "test"}
|
||||
b, err := json.Marshal(expected)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
w := gzip.NewWriter(buf)
|
||||
_, err = w.Write(b)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
e := httptest.New(t, app)
|
||||
// send gzip compressed.
|
||||
e.POST("/").WithHeader("Content-Encoding", "gzip").WithHeader("Content-Type", "application/json").
|
||||
WithBytes(buf.Bytes()).Expect().Status(httptest.StatusOK).Body().Equal(expected.Message)
|
||||
// raw.
|
||||
e.POST("/").WithJSON(expected).Expect().Status(httptest.StatusOK).Body().Equal(expected.Message)
|
||||
}
|
||||
146
_examples/request-body/read-json-struct-validation/main.go
Normal file
146
_examples/request-body/read-json-struct-validation/main.go
Normal file
@@ -0,0 +1,146 @@
|
||||
// Package main shows the validator(latest, version 10) integration with Iris' Context methods of
|
||||
// `ReadJSON`, `ReadXML`, `ReadMsgPack`, `ReadYAML`, `ReadForm`, `ReadQuery`, `ReadBody`.
|
||||
//
|
||||
// You can find more examples of this 3rd-party library at:
|
||||
// https://github.com/go-playground/validator/blob/master/_examples
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
|
||||
// $ go get github.com/go-playground/validator/v10@latest
|
||||
"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)
|
||||
}
|
||||
|
||||
// Use Postman or any tool to perform a POST request
|
||||
// to the http://localhost:8080/user with RAW BODY of:
|
||||
/*
|
||||
{
|
||||
"fname": "",
|
||||
"lname": "",
|
||||
"age": 45,
|
||||
"email": "mail@example.com",
|
||||
"favColor": "#000",
|
||||
"addresses": [{
|
||||
"street": "Eavesdown Docks",
|
||||
"planet": "Persphone",
|
||||
"phone": "none",
|
||||
"city": "Unknown"
|
||||
}]
|
||||
}
|
||||
*/
|
||||
/* The response should be:
|
||||
{
|
||||
"title": "Validation error",
|
||||
"detail": "One or more fields failed to be validated",
|
||||
"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": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
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"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
FavouriteColor string `json:"favColor" validate:"hexcolor|rgb|rgba"`
|
||||
Addresses []*Address `json:"addresses" validate:"required,dive,required"` // a User can have a home and cottage...
|
||||
}
|
||||
|
||||
// Address houses a users 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 {
|
||||
// Handle the error, below you will find the right way to do that...
|
||||
|
||||
if errs, ok := err.(validator.ValidationErrors); ok {
|
||||
// Wrap the errors with JSON format, the underline library returns the errors as interface.
|
||||
validationErrors := wrapValidationErrors(errs)
|
||||
|
||||
// Fire an application/json+problem response and stop the handlers chain.
|
||||
ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
|
||||
Title("Validation error").
|
||||
Detail("One or more fields failed to be validated").
|
||||
Type("/user/validation-errors").
|
||||
Key("errors", validationErrors))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// It's probably an internal JSON error, let's dont give more info here.
|
||||
ctx.StopWithStatus(iris.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(iris.Map{"message": "OK"})
|
||||
}
|
||||
|
||||
func resolveErrorsDocumentation(ctx iris.Context) {
|
||||
ctx.WriteString("A page that should document to web developers or users of the API on how to resolve the validation errors")
|
||||
}
|
||||
62
_examples/request-body/read-json/main.go
Normal file
62
_examples/request-body/read-json/main.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
type Company struct {
|
||||
Name string
|
||||
City string
|
||||
Other string
|
||||
}
|
||||
|
||||
func MyHandler(ctx iris.Context) {
|
||||
var c Company
|
||||
|
||||
if err := ctx.ReadJSON(&c); err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Received: %#+v\n", c)
|
||||
}
|
||||
|
||||
// simple json stuff, read more at https://golang.org/pkg/encoding/json
|
||||
type Person struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
// MyHandler2 reads a collection of Person from JSON post body.
|
||||
func MyHandler2(ctx iris.Context) {
|
||||
var persons []Person
|
||||
err := ctx.ReadJSON(&persons)
|
||||
if err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Received: %#+v\n", persons)
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
app.Post("/", MyHandler)
|
||||
app.Post("/slice", MyHandler2)
|
||||
|
||||
// use Postman or whatever to do a POST request
|
||||
// to the http://localhost:8080 with RAW BODY:
|
||||
/*
|
||||
{
|
||||
"Name": "iris-Go",
|
||||
"City": "New York",
|
||||
"Other": "Something here"
|
||||
}
|
||||
*/
|
||||
// and Content-Type to application/json (optionally but good practise)
|
||||
//
|
||||
// The response should be:
|
||||
// Received: main.Company{Name:"iris-Go", City:"New York", Other:"Something here"}
|
||||
app.Listen(":8080", iris.WithOptimizations)
|
||||
}
|
||||
60
_examples/request-body/read-many/main.go
Normal file
60
_examples/request-body/read-many/main.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
app.Post("/", logAllBody, logJSON, logFormValues, func(ctx iris.Context) {
|
||||
// body, err := ioutil.ReadAll(ctx.Request().Body) once or
|
||||
body, err := ctx.GetBody() // as many times as you need.
|
||||
if err != nil {
|
||||
ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
ctx.WriteString(`The body was empty
|
||||
or iris.WithoutBodyConsumptionOnUnmarshal option is missing from app.Run.
|
||||
Check the terminal window for any queries logs.`)
|
||||
} else {
|
||||
ctx.WriteString("OK body is still:\n")
|
||||
ctx.Write(body)
|
||||
}
|
||||
})
|
||||
|
||||
// With ctx.UnmarshalBody, ctx.ReadJSON, ctx.ReadXML, ctx.ReadForm, ctx.FormValues
|
||||
// and ctx.GetBody methods the default golang and net/http behavior
|
||||
// is to consume the readen data - they are not available on any next handlers in the chain -
|
||||
// to change that behavior just pass the `WithoutBodyConsumptionOnUnmarshal` option.
|
||||
app.Listen(":8080", iris.WithoutBodyConsumptionOnUnmarshal)
|
||||
}
|
||||
|
||||
func logAllBody(ctx iris.Context) {
|
||||
body, err := ctx.GetBody()
|
||||
if err == nil && len(body) > 0 {
|
||||
ctx.Application().Logger().Infof("logAllBody: %s", string(body))
|
||||
}
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
|
||||
func logJSON(ctx iris.Context) {
|
||||
var p interface{}
|
||||
if err := ctx.ReadJSON(&p); err == nil {
|
||||
ctx.Application().Logger().Infof("logJSON: %#+v", p)
|
||||
}
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
|
||||
func logFormValues(ctx iris.Context) {
|
||||
values := ctx.FormValues()
|
||||
if values != nil {
|
||||
ctx.Application().Logger().Infof("logFormValues: %v", values)
|
||||
}
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
37
_examples/request-body/read-msgpack/main.go
Normal file
37
_examples/request-body/read-msgpack/main.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import "github.com/kataras/iris/v12"
|
||||
|
||||
// User example struct to bind to.
|
||||
type User struct {
|
||||
Firstname string `msgpack:"firstname"`
|
||||
Lastname string `msgpack:"lastname"`
|
||||
City string `msgpack:"city"`
|
||||
Age int `msgpack:"age"`
|
||||
}
|
||||
|
||||
// readMsgPack reads a `User` from MsgPack post body.
|
||||
func readMsgPack(ctx iris.Context) {
|
||||
var u User
|
||||
err := ctx.ReadMsgPack(&u)
|
||||
if err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Received: %#+v\n", u)
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Post("/", readMsgPack)
|
||||
|
||||
// POST: http://localhost:8080
|
||||
//
|
||||
// To run the example, use a tool like Postman:
|
||||
// 1. Body: Binary
|
||||
// 2. Select File, select the one from "_examples/response-writer/write-rest" example.
|
||||
// The output should be:
|
||||
// Received: main.User{Firstname:"John", Lastname:"Doe", City:"Neither FBI knows!!!", Age:25}
|
||||
app.Listen(":8080")
|
||||
}
|
||||
29
_examples/request-body/read-query/main.go
Normal file
29
_examples/request-body/read-query/main.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// package main contains an example on how to use the ReadForm, but with the same way you can do the ReadJSON & ReadJSON
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
type MyType struct {
|
||||
Name string `url:"name"`
|
||||
Age int `url:"age"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
var t MyType
|
||||
err := ctx.ReadQuery(&t)
|
||||
if err != nil && !iris.IsErrPath(err) {
|
||||
ctx.StopWithError(iris.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("MyType: %#v", t)
|
||||
})
|
||||
|
||||
// http://localhost:8080?name=iris&age=3
|
||||
app.Listen(":8080")
|
||||
}
|
||||
49
_examples/request-body/read-xml/main.go
Normal file
49
_examples/request-body/read-xml/main.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
|
||||
// use Postman or whatever to do a POST request
|
||||
// to the http://localhost:8080 with RAW BODY:
|
||||
/*
|
||||
<person name="Winston Churchill" age="90">
|
||||
<description>Description of this person, the body of this inner element.</description>
|
||||
</person>
|
||||
*/
|
||||
// and Content-Type to application/xml (optionally but good practise)
|
||||
//
|
||||
// The response should be:
|
||||
// Received: main.person{XMLName:xml.Name{Space:"", Local:"person"}, Name:"Winston Churchill", Age:90, Description:"Description of this person, the body of this inner element."}
|
||||
app.Listen(":8080", iris.WithOptimizations)
|
||||
}
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.Post("/", handler)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// simple xml stuff, read more at https://golang.org/pkg/encoding/xml
|
||||
type person struct {
|
||||
XMLName xml.Name `xml:"person"` // element name
|
||||
Name string `xml:"name,attr"` // ,attr for attribute.
|
||||
Age int `xml:"age,attr"` // ,attr attribute.
|
||||
Description string `xml:"description"` // inner element name, value is its body.
|
||||
}
|
||||
|
||||
func handler(ctx iris.Context) {
|
||||
var p person
|
||||
if err := ctx.ReadXML(&p); err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Received: %#+v", p)
|
||||
}
|
||||
18
_examples/request-body/read-xml/main_test.go
Normal file
18
_examples/request-body/read-xml/main_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestReadXML(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app)
|
||||
|
||||
expectedResponse := `Received: main.person{XMLName:xml.Name{Space:"", Local:"person"}, Name:"Winston Churchill", Age:90, Description:"Description of this person, the body of this inner element."}`
|
||||
send := `<person name="Winston Churchill" age="90"><description>Description of this person, the body of this inner element.</description></person>`
|
||||
|
||||
e.POST("/").WithText(send).Expect().
|
||||
Status(httptest.StatusOK).Body().Equal(expectedResponse)
|
||||
}
|
||||
35
_examples/request-body/read-yaml/main.go
Normal file
35
_examples/request-body/read-yaml/main.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
app.Post("/", handler)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// simple yaml stuff, read more at https://yaml.org/start.html
|
||||
type product struct {
|
||||
Invoice int `yaml:"invoice"`
|
||||
Tax float32 `yaml:"tax"`
|
||||
Total float32 `yaml:"total"`
|
||||
Comments string `yaml:"comments"`
|
||||
}
|
||||
|
||||
func handler(ctx iris.Context) {
|
||||
var p product
|
||||
if err := ctx.ReadYAML(&p); err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Received: %#+v", p)
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
app.Listen(":8080")
|
||||
}
|
||||
24
_examples/request-body/read-yaml/main_test.go
Normal file
24
_examples/request-body/read-yaml/main_test.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestReadYAML(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app)
|
||||
|
||||
expectedResponse := `Received: main.product{Invoice:34843, Tax:251.42, Total:4443.52, Comments:"Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338."}`
|
||||
send := `invoice: 34843
|
||||
tax : 251.42
|
||||
total: 4443.52
|
||||
comments: >
|
||||
Late afternoon is best.
|
||||
Backup contact is Nancy
|
||||
Billsmer @ 338-4338.`
|
||||
|
||||
e.POST("/").WithHeader("Content-Type", "application/x-yaml").WithBytes([]byte(send)).Expect().
|
||||
Status(httptest.StatusOK).Body().Equal(expectedResponse)
|
||||
}
|
||||
Reference in New Issue
Block a user