From 247a558394f988e7019b0a9bc1ea2bfa62cc8d75 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Tue, 24 Jul 2018 04:33:53 +0300 Subject: [PATCH] Add example for struct validation(3rd-party) through json request body binding Former-commit-id: 78bbbe068f219e5a264951c900b77cb9b70f2079 --- README.md | 556 +++++++++--------- _examples/README.md | 1 + .../read-json-struct-validation/main.go | 143 +++++ _examples/http_request/upload-files/main.go | 45 ++ _examples/miscellaneous/file-logger/main.go | 27 +- _examples/miscellaneous/recover/main.go | 1 - 6 files changed, 480 insertions(+), 293 deletions(-) create mode 100644 _examples/http_request/read-json-struct-validation/main.go diff --git a/README.md b/README.md index f51eaa85..fc4ebc44 100644 --- a/README.md +++ b/README.md @@ -1,278 +1,278 @@ -# Iris Web Framework - - - -[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.6-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases) - -Iris is a fast, simple yet fully featured and very efficient web framework for Go. - -Iris provides a beautifully expressive and easy to use foundation for your next website or API. - -Finally, a real expressjs equivalent for the Go Programming Language. - -Learn what [others say about Iris](#support) and [star](https://github.com/kataras/iris/stargazers) this github repository to stay [up to date](https://facebook.com/iris.framework). - -## Backers - -Thank you to all our backers! 🙏 [Become a backer](https://iris-go.com/donate) - - - -```sh -$ cat _examples/cookies/basic/main.go -``` - -```go -package main - -import "github.com/kataras/iris" - -func newApp() *iris.Application { - app := iris.New() - - // Set A Cookie. - app.Get("/cookies/{name}/{value}", func(ctx iris.Context) { - name := ctx.Params().Get("name") - value := ctx.Params().Get("value") - - ctx.SetCookieKV(name, value) - - ctx.Writef("cookie added: %s = %s", name, value) - }) - - // Retrieve A Cookie. - app.Get("/cookies/{name}", func(ctx iris.Context) { - name := ctx.Params().Get("name") - - value := ctx.GetCookie(name) - - ctx.WriteString(value) - }) - - // Delete A Cookie. - app.Delete("/cookies/{name}", func(ctx iris.Context) { - name := ctx.Params().Get("name") - - ctx.RemoveCookie(name) - - ctx.Writef("cookie %s removed", name) - }) - - return app -} - -func main() { - app := newApp() - - // GET: http://localhost:8080/cookies/my_name/my_value - // GET: http://localhost:8080/cookies/my_name - // DELETE: http://localhost:8080/cookies/my_name - app.Run(iris.Addr(":8080")) -} -``` - -* Alternatively, use a regular `http.Cookie`: `ctx.SetCookie(&http.Cookie{...})` -* If you want to set custom the path: `ctx.SetCookieKV(name, value, iris.CookiePath("/custom/path/cookie/will/be/stored"))`. -* If you want to be available only to the current request path: `ctx.SetCookieKV(name, value, iris.CookieCleanPath /* or iris.CookiePath("") */)` - * `iris.CookieExpires(time.Duration)` - * `iris.CookieHTTPOnly(false)` -* `ctx.Request().Cookie(name)` is also available, it's the `net/http` approach -* Learn more about path parameter's types by clicking [here](_examples/routing/dynamic-path/main.go#L31). - -### Testing your Application? Easy with Iris - -```go -package main - -import ( - "fmt" - "testing" - - "github.com/kataras/iris/httptest" -) - -// go test -v -run=TestCookiesBasic$ -func TestCookiesBasic(t *testing.T) { - app := newApp() - e := httptest.New(t, app, httptest.URL("http://example.com")) - - cookieName, cookieValue := "my_cookie_name", "my_cookie_value" - - // Test Set A Cookie. - t1 := e.GET(fmt.Sprintf("/cookies/%s/%s", cookieName, cookieValue)).Expect().Status(httptest.StatusOK) - t1.Cookie(cookieName).Value().Equal(cookieValue) // validate cookie's existence, it should be there now. - t1.Body().Contains(cookieValue) - - path := fmt.Sprintf("/cookies/%s", cookieName) - - // Test Retrieve A Cookie. - t2 := e.GET(path).Expect().Status(httptest.StatusOK) - t2.Body().Equal(cookieValue) - - // Test Remove A Cookie. - t3 := e.DELETE(path).Expect().Status(httptest.StatusOK) - t3.Body().Contains(cookieName) - - t4 := e.GET(path).Expect().Status(httptest.StatusOK) - t4.Cookies().Empty() - t4.Body().Empty() -} -``` - -### Serve your Application - -```sh -$ go run main.go -Now listening on: http://localhost:8080 -Application Started. Press CTRL+C to shut down. -_ -``` - -## Installation - -The only requirement is the [Go Programming Language](https://golang.org/dl/) - -```sh -$ go get -u github.com/kataras/iris -``` - -Iris takes advantage of the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature. You get truly reproducible builds, as this method guards against upstream renames and deletes. - -[![Iris vs .NET Core(C#) vs Node.js (Express)](https://iris-go.com/images/benchmark-new-gray.png)](_benchmarks/README_UNIX.md) - -_Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_ - -
-Benchmarks from third-party source over the rest web frameworks - -![Comparison with other frameworks](https://raw.githubusercontent.com/smallnest/go-web-framework-benchmark/4db507a22c964c9bc9774c5b31afdc199a0fe8b7/benchmark.png) - -
- -## Support - -- [HISTORY](HISTORY.md#tu-05-june-2018--v1066) file is your best friend, it contains information about the latest features and changes -- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues) -- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com) -- Complete our form-based user experience report by clicking [here](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link) -- Do you like the framework? Tweet something about it! The People have spoken: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- -For more information about contributing to the Iris project please check the [CONTRIBUTING.md](CONTRIBUTING.md) file. - -[List of all Contributors](https://github.com/kataras/iris/graphs/contributors) - -## Learn - -First of all, the most correct way to begin with a web framework is to learn the basics of the programming language and the standard `http` capabilities, if your web application is a very simple personal project without performance and maintainability requirements you may want to proceed just with the standard packages. After that follow the guidelines: - -- Navigate through **100+1** **[examples](_examples)** and some [iris starter kits](#iris-starter-kits) we crafted for you -- Read the [godocs](https://godoc.org/github.com/kataras/iris) for any details -- Prepare a cup of coffee or tea, whatever pleases you the most, and read some [articles](#articles) we found for you - -### Iris starter kits - - - -1. [A basic web app built in Iris for Go](https://github.com/gauravtiwari/go_iris_app) -2. [A mini social-network created with the awesome Iris💖💖](https://github.com/iris-contrib/Iris-Mini-Social-Network) -3. [Iris isomorphic react/hot reloadable/redux/css-modules starter kit](https://github.com/iris-contrib/iris-starter-kit) -4. [Demo project with react using typescript and Iris](https://github.com/ionutvilie/react-ts) -5. [Self-hosted Localization Management Platform built with Iris and Angular](https://github.com/iris-contrib/parrot) -6. [Iris + Docker and Kubernetes](https://github.com/iris-contrib/cloud-native-go) -7. [Quickstart for Iris with Nanobox](https://guides.nanobox.io/golang/iris/from-scratch) -8. [A Hasura starter project with a ready to deploy Golang hello-world web app with IRIS](https://hasura.io/hub/project/hasura/hello-golang-iris) - -> Did you build something similar? Let us [know](https://github.com/kataras/iris/pulls)! - -### Middleware - -Iris has a great collection of handlers[[1]](middleware/)[[2]](https://github.com/iris-contrib/middleware) that you can use side by side with your web apps. However you are not limited to them - you are free to use any third-party middleware that is compatible with the [net/http](https://golang.org/pkg/net/http/) package, [_examples/convert-handlers](_examples/convert-handlers) will show you the way. - -Iris, unlike others, is 100% compatible with the standards and that's why the majority of the big companies that adapt Go to their workflow, like a very famous US Television Network, trust Iris; it's up-to-date and it will be always aligned with the std `net/http` package which is modernized by the Go Authors on each new release of the Go Programming Language. - -### Articles - -* [A Todo MVC Application using Iris and Vue.js](https://hackernoon.com/a-todo-mvc-application-using-iris-and-vue-js-5019ff870064) -* [A Hasura starter project with a ready to deploy Golang hello-world web app with IRIS](https://bit.ly/2lmKaAZ) -* [Top 6 web frameworks for Go as of 2017](https://blog.usejournal.com/top-6-web-frameworks-for-go-as-of-2017-23270e059c4b) -* [Iris Go Framework + MongoDB](https://medium.com/go-language/iris-go-framework-mongodb-552e349eab9c) -* [How to build a file upload form using DropzoneJS and Go](https://hackernoon.com/how-to-build-a-file-upload-form-using-dropzonejs-and-go-8fb9f258a991) -* [How to display existing files on server using DropzoneJS and Go](https://hackernoon.com/how-to-display-existing-files-on-server-using-dropzonejs-and-go-53e24b57ba19) -* [Iris, a modular web framework](https://medium.com/@corebreaker/iris-web-cd684b4685c7) -* [Go vs .NET Core in terms of HTTP performance](https://medium.com/@kataras/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8) -* [Iris Go vs .NET Core Kestrel in terms of HTTP performance](https://hackernoon.com/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5) -* [How to Turn an Android Device into a Web Server](https://twitter.com/ThePracticalDev/status/892022594031017988) -* [Deploying a Iris Golang app in hasura](https://medium.com/@HasuraHQ/deploy-an-iris-golang-app-with-backend-apis-in-minutes-25a559bf530b) -* [A URL Shortener Service using Go, Iris and Bolt](https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7) - -### Video Courses - -* [Daily Coding - Web Framework Golang: Iris Framework]( https://www.youtube.com/watch?v=BmOLFQ29J3s) by WarnabiruTV, source: youtube, cost: **FREE** -* [Tutorial Golang MVC dengan Iris Framework & Mongo DB](https://www.youtube.com/watch?v=uXiNYhJqh2I&list=PLMrwI6jIZn-1tzskocnh1pptKhVmWdcbS) (19 parts so far) by Musobar Media, source: youtube, cost: **FREE** -* [Go/Golang 27 - Iris framework : Routage de base](https://www.youtube.com/watch?v=rQxRoN6ub78) by stephgdesign, source: youtube, cost: **FREE** -* [Go/Golang 28 - Iris framework : Templating](https://www.youtube.com/watch?v=nOKYV073S2Y) by stephgdesignn, source: youtube, cost: **FREE** -* [Go/Golang 29 - Iris framework : Paramètres](https://www.youtube.com/watch?v=K2FsprfXs1E) by stephgdesign, source: youtube, cost: **FREE** -* [Go/Golang 30 - Iris framework : Les middelwares](https://www.youtube.com/watch?v=BLPy1So6bhE) by stephgdesign, source: youtube, cost: **FREE** -* [Go/Golang 31 - Iris framework : Les sessions](https://www.youtube.com/watch?v=RnBwUrwgEZ8) by stephgdesign, source: youtube, cost: **FREE** - -### Get hired - -There are many companies and start-ups looking for Go web developers with Iris experience as requirement, we are searching for you every day and we post those information via our [facebook page](https://www.facebook.com/iris.framework), like the page to get notified, we have already posted some of them. - -## License - -Iris is licensed under the [3-Clause BSD License](LICENSE). Iris is 100% free and open-source software. - -For any questions regarding the license please send [e-mail](mailto:kataras2006@hotmail.com?subject=Iris%20License). +# Iris Web Framework + + + +[![build status](https://img.shields.io/travis/kataras/iris/master.svg?style=flat-square)](https://travis-ci.org/kataras/iris) [![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/kataras/iris) [![vscode-iris](https://img.shields.io/badge/ext%20-vscode-0c77e3.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=kataras2006.iris) [![chat](https://img.shields.io/badge/community-%20chat-00BCD4.svg?style=flat-square)](https://kataras.rocket.chat/channel/iris) [![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://iris-go.com/v10/recipe) [![release](https://img.shields.io/badge/release%20-v10.6-0077b3.svg?style=flat-square)](https://github.com/kataras/iris/releases) + +Iris is a fast, simple yet fully featured and very efficient web framework for Go. + +Iris provides a beautifully expressive and easy to use foundation for your next website or API. + +Finally, a real expressjs equivalent for the Go Programming Language. + +Learn what [others say about Iris](#support) and [star](https://github.com/kataras/iris/stargazers) this github repository to stay [up to date](https://facebook.com/iris.framework). + +## Backers + +Thank you to all our backers! 🙏 [Become a backer](https://iris-go.com/donate) + + + +```sh +$ cat _examples/cookies/basic/main.go +``` + +```go +package main + +import "github.com/kataras/iris" + +func newApp() *iris.Application { + app := iris.New() + + // Set A Cookie. + app.Get("/cookies/{name}/{value}", func(ctx iris.Context) { + name := ctx.Params().Get("name") + value := ctx.Params().Get("value") + + ctx.SetCookieKV(name, value) + + ctx.Writef("cookie added: %s = %s", name, value) + }) + + // Retrieve A Cookie. + app.Get("/cookies/{name}", func(ctx iris.Context) { + name := ctx.Params().Get("name") + + value := ctx.GetCookie(name) + + ctx.WriteString(value) + }) + + // Delete A Cookie. + app.Delete("/cookies/{name}", func(ctx iris.Context) { + name := ctx.Params().Get("name") + + ctx.RemoveCookie(name) + + ctx.Writef("cookie %s removed", name) + }) + + return app +} + +func main() { + app := newApp() + + // GET: http://localhost:8080/cookies/my_name/my_value + // GET: http://localhost:8080/cookies/my_name + // DELETE: http://localhost:8080/cookies/my_name + app.Run(iris.Addr(":8080")) +} +``` + +* Alternatively, use a regular `http.Cookie`: `ctx.SetCookie(&http.Cookie{...})` +* If you want to set custom the path: `ctx.SetCookieKV(name, value, iris.CookiePath("/custom/path/cookie/will/be/stored"))`. +* If you want to be available only to the current request path: `ctx.SetCookieKV(name, value, iris.CookieCleanPath /* or iris.CookiePath("") */)` + * `iris.CookieExpires(time.Duration)` + * `iris.CookieHTTPOnly(false)` +* `ctx.Request().Cookie(name)` is also available, it's the `net/http` approach +* Learn more about path parameter's types by clicking [here](_examples/routing/dynamic-path/main.go#L31). + +### Testing your Application? Easy with Iris + +```go +package main + +import ( + "fmt" + "testing" + + "github.com/kataras/iris/httptest" +) + +// go test -v -run=TestCookiesBasic$ +func TestCookiesBasic(t *testing.T) { + app := newApp() + e := httptest.New(t, app, httptest.URL("http://example.com")) + + cookieName, cookieValue := "my_cookie_name", "my_cookie_value" + + // Test Set A Cookie. + t1 := e.GET(fmt.Sprintf("/cookies/%s/%s", cookieName, cookieValue)).Expect().Status(httptest.StatusOK) + t1.Cookie(cookieName).Value().Equal(cookieValue) // validate cookie's existence, it should be there now. + t1.Body().Contains(cookieValue) + + path := fmt.Sprintf("/cookies/%s", cookieName) + + // Test Retrieve A Cookie. + t2 := e.GET(path).Expect().Status(httptest.StatusOK) + t2.Body().Equal(cookieValue) + + // Test Remove A Cookie. + t3 := e.DELETE(path).Expect().Status(httptest.StatusOK) + t3.Body().Contains(cookieName) + + t4 := e.GET(path).Expect().Status(httptest.StatusOK) + t4.Cookies().Empty() + t4.Body().Empty() +} +``` + +### Serve your Application + +```sh +$ go run main.go +Now listening on: http://localhost:8080 +Application Started. Press CTRL+C to shut down. +_ +``` + +## Installation + +The only requirement is the [Go Programming Language](https://golang.org/dl/) + +```sh +$ go get -u github.com/kataras/iris +``` + +Iris takes advantage of the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature. You get truly reproducible builds, as this method guards against upstream renames and deletes. + +[![Iris vs .NET Core(C#) vs Node.js (Express)](https://iris-go.com/images/benchmark-new-gray.png)](_benchmarks/README_UNIX.md) + +_Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_ + +
+Benchmarks from third-party source over the rest web frameworks + +![Comparison with other frameworks](https://raw.githubusercontent.com/smallnest/go-web-framework-benchmark/4db507a22c964c9bc9774c5b31afdc199a0fe8b7/benchmark.png) + +
+ +## Support + +- [HISTORY](HISTORY.md#tu-05-june-2018--v1066) file is your best friend, it contains information about the latest features and changes +- Did you happen to find a bug? Post it at [github issues](https://github.com/kataras/iris/issues) +- Do you have any questions or need to speak with someone experienced to solve a problem at real-time? Join us to the [community chat](https://chat.iris-go.com) +- Complete our form-based user experience report by clicking [here](https://docs.google.com/forms/d/e/1FAIpQLSdCxZXPANg_xHWil4kVAdhmh7EBBHQZ_4_xSZVDL-oCC_z5pA/viewform?usp=sf_link) +- Do you like the framework? Tweet something about it! The People have spoken: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ +For more information about contributing to the Iris project please check the [CONTRIBUTING.md](CONTRIBUTING.md) file. + +[List of all Contributors](https://github.com/kataras/iris/graphs/contributors) + +## Learn + +First of all, the most correct way to begin with a web framework is to learn the basics of the programming language and the standard `http` capabilities, if your web application is a very simple personal project without performance and maintainability requirements you may want to proceed just with the standard packages. After that follow the guidelines: + +- Navigate through **100+1** **[examples](_examples)** and some [iris starter kits](#iris-starter-kits) we crafted for you +- Read the [godocs](https://godoc.org/github.com/kataras/iris) for any details +- Prepare a cup of coffee or tea, whatever pleases you the most, and read some [articles](#articles) we found for you + +### Iris starter kits + + + +1. [A basic web app built in Iris for Go](https://github.com/gauravtiwari/go_iris_app) +2. [A mini social-network created with the awesome Iris💖💖](https://github.com/iris-contrib/Iris-Mini-Social-Network) +3. [Iris isomorphic react/hot reloadable/redux/css-modules starter kit](https://github.com/iris-contrib/iris-starter-kit) +4. [Demo project with react using typescript and Iris](https://github.com/ionutvilie/react-ts) +5. [Self-hosted Localization Management Platform built with Iris and Angular](https://github.com/iris-contrib/parrot) +6. [Iris + Docker and Kubernetes](https://github.com/iris-contrib/cloud-native-go) +7. [Quickstart for Iris with Nanobox](https://guides.nanobox.io/golang/iris/from-scratch) +8. [A Hasura starter project with a ready to deploy Golang hello-world web app with IRIS](https://hasura.io/hub/project/hasura/hello-golang-iris) + +> Did you build something similar? Let us [know](https://github.com/kataras/iris/pulls)! + +### Middleware + +Iris has a great collection of handlers[[1]](middleware/)[[2]](https://github.com/iris-contrib/middleware) that you can use side by side with your web apps. However you are not limited to them - you are free to use any third-party middleware that is compatible with the [net/http](https://golang.org/pkg/net/http/) package, [_examples/convert-handlers](_examples/convert-handlers) will show you the way. + +Iris, unlike others, is 100% compatible with the standards and that's why the majority of the big companies that adapt Go to their workflow, like a very famous US Television Network, trust Iris; it's up-to-date and it will be always aligned with the std `net/http` package which is modernized by the Go Authors on each new release of the Go Programming Language. + +### Articles + +* [A Todo MVC Application using Iris and Vue.js](https://hackernoon.com/a-todo-mvc-application-using-iris-and-vue-js-5019ff870064) +* [A Hasura starter project with a ready to deploy Golang hello-world web app with IRIS](https://bit.ly/2lmKaAZ) +* [Top 6 web frameworks for Go as of 2017](https://blog.usejournal.com/top-6-web-frameworks-for-go-as-of-2017-23270e059c4b) +* [Iris Go Framework + MongoDB](https://medium.com/go-language/iris-go-framework-mongodb-552e349eab9c) +* [How to build a file upload form using DropzoneJS and Go](https://hackernoon.com/how-to-build-a-file-upload-form-using-dropzonejs-and-go-8fb9f258a991) +* [How to display existing files on server using DropzoneJS and Go](https://hackernoon.com/how-to-display-existing-files-on-server-using-dropzonejs-and-go-53e24b57ba19) +* [Iris, a modular web framework](https://medium.com/@corebreaker/iris-web-cd684b4685c7) +* [Go vs .NET Core in terms of HTTP performance](https://medium.com/@kataras/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8) +* [Iris Go vs .NET Core Kestrel in terms of HTTP performance](https://hackernoon.com/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5) +* [How to Turn an Android Device into a Web Server](https://twitter.com/ThePracticalDev/status/892022594031017988) +* [Deploying a Iris Golang app in hasura](https://medium.com/@HasuraHQ/deploy-an-iris-golang-app-with-backend-apis-in-minutes-25a559bf530b) +* [A URL Shortener Service using Go, Iris and Bolt](https://medium.com/@kataras/a-url-shortener-service-using-go-iris-and-bolt-4182f0b00ae7) + +### Video Courses + +* [Daily Coding - Web Framework Golang: Iris Framework]( https://www.youtube.com/watch?v=BmOLFQ29J3s) by WarnabiruTV, source: youtube, cost: **FREE** +* [Tutorial Golang MVC dengan Iris Framework & Mongo DB](https://www.youtube.com/watch?v=uXiNYhJqh2I&list=PLMrwI6jIZn-1tzskocnh1pptKhVmWdcbS) (19 parts so far) by Musobar Media, source: youtube, cost: **FREE** +* [Go/Golang 27 - Iris framework : Routage de base](https://www.youtube.com/watch?v=rQxRoN6ub78) by stephgdesign, source: youtube, cost: **FREE** +* [Go/Golang 28 - Iris framework : Templating](https://www.youtube.com/watch?v=nOKYV073S2Y) by stephgdesignn, source: youtube, cost: **FREE** +* [Go/Golang 29 - Iris framework : Paramètres](https://www.youtube.com/watch?v=K2FsprfXs1E) by stephgdesign, source: youtube, cost: **FREE** +* [Go/Golang 30 - Iris framework : Les middelwares](https://www.youtube.com/watch?v=BLPy1So6bhE) by stephgdesign, source: youtube, cost: **FREE** +* [Go/Golang 31 - Iris framework : Les sessions](https://www.youtube.com/watch?v=RnBwUrwgEZ8) by stephgdesign, source: youtube, cost: **FREE** + +### Get hired + +There are many companies and start-ups looking for Go web developers with Iris experience as requirement, we are searching for you every day and we post those information via our [facebook page](https://www.facebook.com/iris.framework), like the page to get notified, we have already posted some of them. + +## License + +Iris is licensed under the [3-Clause BSD License](LICENSE). Iris is 100% free and open-source software. + +For any questions regarding the license please send [e-mail](mailto:kataras2006@hotmail.com?subject=Iris%20License). diff --git a/_examples/README.md b/_examples/README.md index b7df1206..87e3fdc4 100644 --- a/_examples/README.md +++ b/_examples/README.md @@ -325,6 +325,7 @@ You can serve [quicktemplate](https://github.com/valyala/quicktemplate) and [her ### How to Read from `context.Request() *http.Request` - [Read JSON](http_request/read-json/main.go) + * [Struct Validation](http_request/read-json-struct-validation/main.go) - [Read XML](http_request/read-xml/main.go) - [Read Form](http_request/read-form/main.go) - [Read Custom per type](http_request/read-custom-per-type/main.go) diff --git a/_examples/http_request/read-json-struct-validation/main.go b/_examples/http_request/read-json-struct-validation/main.go new file mode 100644 index 00000000..f7beedc0 --- /dev/null +++ b/_examples/http_request/read-json-struct-validation/main.go @@ -0,0 +1,143 @@ +// Package main shows the validator(latest, version 9) integration with Iris. +// You can find more examples like this at: https://github.com/go-playground/validator/blob/v9/_examples +package main + +import ( + "fmt" + + "github.com/kataras/iris" + // $ go get gopkg.in/go-playground/validator.v9 + "gopkg.in/go-playground/validator.v9" +) + +// User contains user information. +type User struct { + FirstName string `json:"fname"` + LastName string `json:"lname"` + 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 person 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"` +} + +// Use a single instance of Validate, it caches struct info. +var validate *validator.Validate + +func main() { + validate = validator.New() + + // Register validation for 'User' + // NOTE: only have to register a non-pointer type for 'User', validator + // interanlly dereferences during it's type checks. + validate.RegisterStructValidation(UserStructLevelValidation, User{}) + + app := iris.New() + app.Post("/user", func(ctx iris.Context) { + var user User + if err := ctx.ReadJSON(&user); err != nil { + // Handle error. + } + + // Returns InvalidValidationError for bad validation input, nil or ValidationErrors ( []FieldError ) + err := validate.Struct(user) + if err != nil { + + // This check is only needed when your code could produce + // an invalid value for validation such as interface with nil + // value most including myself do not usually have code like this. + if _, ok := err.(*validator.InvalidValidationError); ok { + ctx.StatusCode(iris.StatusInternalServerError) + ctx.WriteString(err.Error()) + return + } + + ctx.StatusCode(iris.StatusBadRequest) + for _, err := range err.(validator.ValidationErrors) { + fmt.Println() + fmt.Println(err.Namespace()) + fmt.Println(err.Field()) + fmt.Println(err.StructNamespace()) // Can differ when a custom TagNameFunc is registered or. + fmt.Println(err.StructField()) // By passing alt name to ReportError like below. + fmt.Println(err.Tag()) + fmt.Println(err.ActualTag()) + fmt.Println(err.Kind()) + fmt.Println(err.Type()) + fmt.Println(err.Value()) + fmt.Println(err.Param()) + fmt.Println() + + // Or collect these as json objects + // and send back to the client the collected errors via ctx.JSON + // { + // "namespace": err.Namespace(), + // "field": err.Field(), + // "struct_namespace": err.StructNamespace(), + // "struct_field": err.StructField(), + // "tag": err.Tag(), + // "actual_tag": err.ActualTag(), + // "kind": err.Kind().String(), + // "type": err.Type().String(), + // "value": fmt.Sprintf("%v", err.Value()), + // "param": err.Param(), + // } + } + + // from here you can create your own error messages in whatever language you wish. + return + } + + // save user to database. + }) + + // use Postman or whatever to do a POST request + // to the http://localhost:8080/user with RAW BODY: + /* + { + "fname": "", + "lname": "", + "age": 45, + "email": "mail@example.com", + "favColor": "#000", + "addresses": [{ + "street": "Eavesdown Docks", + "planet": "Persphone", + "phone": "none", + "city": "Unknown" + }] + } + */ + // Content-Type to application/json (optionally but good practise). + // This request will fail due to the empty `User.FirstName` (fname in json) + // and `User.LastName` (lname in json). + // Check your iris' application terminal output. + app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed)) +} + +// UserStructLevelValidation contains custom struct level validations that don't always +// make sense at the field validation level. For Example this function validates that either +// FirstName or LastName exist; could have done that with a custom field validation but then +// would have had to add it to both fields duplicating the logic + overhead, this way it's +// only validated once. +// +// NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way +// hooks right into validator and you can combine with validation tags and still have a +// common error output format. +func UserStructLevelValidation(sl validator.StructLevel) { + + user := sl.Current().Interface().(User) + + if len(user.FirstName) == 0 && len(user.LastName) == 0 { + sl.ReportError(user.FirstName, "FirstName", "fname", "fnameorlname", "") + sl.ReportError(user.LastName, "LastName", "lname", "fnameorlname", "") + } + + // plus can to more, even with different tag than "fnameorlname". +} diff --git a/_examples/http_request/upload-files/main.go b/_examples/http_request/upload-files/main.go index b94bc02f..d73bdd23 100644 --- a/_examples/http_request/upload-files/main.go +++ b/_examples/http_request/upload-files/main.go @@ -5,6 +5,8 @@ import ( "fmt" "io" "mime/multipart" + "os" + "path/filepath" "strconv" "strings" "time" @@ -44,10 +46,53 @@ func main() { ctx.UploadFormFiles("./uploads", beforeSave) }) + app.Post("/upload_manual", func(ctx iris.Context) { + // Get the max post value size passed via iris.WithPostMaxMemory. + maxSize := ctx.Application().ConfigurationReadOnly().GetPostMaxMemory() + + err := ctx.Request().ParseMultipartForm(maxSize) + if err != nil { + ctx.StatusCode(iris.StatusInternalServerError) + ctx.WriteString(err.Error()) + return + } + + form := ctx.Request().MultipartForm + + files := form.File["files[]"] + failures := 0 + for _, file := range files { + _, err = saveUploadedFile(file, "./uploads") + if err != nil { + failures++ + ctx.Writef("failed to upload: %s\n", file.Filename) + } + } + ctx.Writef("%d files uploaded", len(files)-failures) + }) + // start the server at http://localhost:8080 with post limit at 32 MB. app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(32<<20)) } +func saveUploadedFile(fh *multipart.FileHeader, destDirectory string) (int64, error) { + src, err := fh.Open() + if err != nil { + return 0, err + } + defer src.Close() + + out, err := os.OpenFile(filepath.Join(destDirectory, fh.Filename), + os.O_WRONLY|os.O_CREATE, os.FileMode(0666)) + + if err != nil { + return 0, err + } + defer out.Close() + + return io.Copy(out, src) +} + func beforeSave(ctx iris.Context, file *multipart.FileHeader) { ip := ctx.RemoteAddr() // make sure you format the ip in a way diff --git a/_examples/miscellaneous/file-logger/main.go b/_examples/miscellaneous/file-logger/main.go index 59b98a1d..49155d69 100644 --- a/_examples/miscellaneous/file-logger/main.go +++ b/_examples/miscellaneous/file-logger/main.go @@ -7,8 +7,7 @@ import ( "github.com/kataras/iris" ) -// get a filename based on the date, file logs works that way the most times -// but these are just a sugar. +// Get a filename based on the date, just for the sugar. func todayFilename() string { today := time.Now().Format("Jan 02 2006") return today + ".txt" @@ -16,7 +15,7 @@ func todayFilename() string { func newLogFile() *os.File { filename := todayFilename() - // open an output file, this will append to the today's file if server restarted. + // Open the file, this will append to the today's file if server restarted. f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { panic(err) @@ -30,20 +29,20 @@ func main() { defer f.Close() app := iris.New() - // attach the file as logger, remember, iris' app logger is just an io.Writer. - app.Logger().SetOutput(newLogFile()) + // Attach the file as logger, remember, iris' app logger is just an io.Writer. + // Use the following code if you need to write the logs to file and console at the same time. + // app.Logger().SetOutput(io.MultiWriter(f, os.Stdout)) + app.Logger().SetOutput(f) - app.Get("/", func(ctx iris.Context) { + app.Get("/ping", func(ctx iris.Context) { // for the sake of simplicity, in order see the logs at the ./_today_.txt - ctx.Application().Logger().Info("Request path: " + ctx.Path()) - ctx.Writef("hello") + ctx.Application().Logger().Infof("Request path: %s", ctx.Path()) + ctx.WriteString("pong") }) - // navigate to http://localhost:8080 - // and open the ./logs.txt file - if err := app.Run(iris.Addr(":8080"), iris.WithoutBanner); err != nil { - if err != iris.ErrServerClosed { - app.Logger().Warn("Shutdown with error: " + err.Error()) - } + // Navigate to http://localhost:8080/ping + // and open the ./logs{TODAY}.txt file. + if err := app.Run(iris.Addr(":8080"), iris.WithoutBanner, iris.WithoutServerError(iris.ErrServerClosed)); err != nil { + app.Logger().Warn("Shutdown with error: " + err.Error()) } } diff --git a/_examples/miscellaneous/recover/main.go b/_examples/miscellaneous/recover/main.go index 9b5b7dc5..f74f19a0 100644 --- a/_examples/miscellaneous/recover/main.go +++ b/_examples/miscellaneous/recover/main.go @@ -8,7 +8,6 @@ import ( func main() { app := iris.New() - // use this recover(y) middleware app.Use(recover.New()) i := 0