README
¶
Examples
Please do learn how net/http std package works, first.
This folder provides easy to understand code snippets on how to get started with iris micro web framework.
It doesn't always contain the "best ways" but it does cover each important feature that will make you so excited to GO with iris!
Running the examples
- Install the Go Programming Language, version 1.9+ from here.
- Install Iris:
go get -u github.com/kataras/iris
- Install any external packages that required by the examples
External packages
cd _examples && go get ./...
# or
go get github.com/iris-contrib/middleware/...
go get github.com/betacraft/yaag/irisyaag
go get github.com/markbates/goth/...
go get github.com/casbin/casbin
go get github.com/aws/aws-sdk-go/...
go get github.com/getsentry/raven-go/...
go get github.com/prometheus/client_golang/...
go get github.com/didip/tollbooth
go get github.com/valyala/quicktemplate
go get github.com/shiyanhui/hero
go get github.com/go-xorm/xorm
go get github.com/nfnt/resize
go get github.com/dgrijalva/jwt-go
go get github.com/newrelic/go-agent
go get github.com/valyala/tcplisten
go get github.com/kataras/bindata/cmd/bindata
go get github.com/jmespath/go-jmespath
And execute
$ cd $GOPATH/src/github.com/kataras/iris/_examples/overview
$ go run main.go
Test the examples by opening a terminal window and execute:
GOCACHE=off && cd _examples && go test -v ./...
Overview
- Hello world!
- Hello WebAssemply! NEW
- Glimpse
- Tutorial: Online Visitors
- Tutorial: A Todo MVC Application using Iris and Vue.js
- Tutorial: URL Shortener using BoltDB
- Tutorial: How to turn your Android Device into a fully featured Web Server (MUST)
- POC: Convert the medium-sized project "Parrot" from native to Iris
- POC: Isomorphic react/hot reloadable/redux/css-modules starter kit
- Tutorial: DropzoneJS Uploader
- Tutorial: Caddy
- Tutorial:Iris Go Framework + MongoDB
- Tutorial: API for Apache Kafka NEW
Structuring
Nothing stops you from using your favorite folder structure. Iris is a low level web framework, it has got MVC first-class support but it doesn't limit your folder structure, this is your choice.
Structuring depends on your own needs. We can't tell you how to design your own application for sure but you're free to take a closer look to the examples below; you may find something useful that you can borrow for your app;
- Bootstrapper
- MVC with Repository and Service layer Overview
- Login (MVC with Single Responsibility package)
- Login (MVC with Datamodels, Datasource, Repository and Service layer)
HTTP Listening
- Common, with address
- UNIX socket file
- TLS
- Letsencrypt (Automatic Certifications)
- Notify on shutdown
- Custom TCP Listener
- Custom HTTP Server
- Graceful Shutdown
Configuration
Routing, Grouping, Dynamic Path Parameters, "Macros" and Custom Context
app.Get("{userid:int min(1)}", myHandler)
app.Post("{asset:path}", myHandler)
app.Put("{custom:string regexp([a-z]+)}", myHandler)
Note: unlike other routers you'd seen, iris' router can handle things like these:
// Matches all GET requests prefixed with "/assets/"
app.Get("/assets/{asset:path}", assetsWildcardHandler)
// Matches only GET "/"
app.Get("/", indexHandler)
// Matches only GET "/about"
app.Get("/about", aboutHandler)
// Matches all GET requests prefixed with "/profile/"
// and followed by a single path part
app.Get("/profile/{username:string}", userHandler)
// Matches only GET "/profile/me" because
// it does not conflict with /profile/{username:string}
// or the root wildcard {root:path}
app.Get("/profile/me", userHandler)
// Matches all GET requests prefixed with /users/
// and followed by a number which should be equal or bigger than 1
app.Get("/user/{userid:int min(1)}", getUserHandler)
// Matches all requests DELETE prefixed with /users/
// and following by a number which should be equal or bigger than 1
app.Delete("/user/{userid:int min(1)}", deleteUserHandler)
// Matches all GET requests except "/", "/about", anything starts with "/assets/" etc...
// because it does not conflict with the rest of the routes.
app.Get("{root:path}", rootWildcardHandler)
Navigate through examples for a better understanding.
- Overview
- Basic
- Controllers
- Custom HTTP Errors
- Dynamic Path
- Write your own custom parameter types NEW
- Reverse routing
- Custom Router (high-level) NEW
- Custom Wrapper
- Custom Context
- Route State
- Writing a middleware
Versioning
hero
- Basic
- Overview
- Sessions NEW
- Yet another dependency injection example and good practises at general NEW
MVC
Iris has first-class support for the MVC (Model View Controller) pattern, you'll not find these stuff anywhere else in the Go world.
Iris web framework supports Request data, Models, Persistence Data and Binding with the fastest possible execution.
Characteristics
All HTTP Methods are supported, for example if want to serve GET
then the controller should have a function named Get()
,
you can define more than one method function to serve in the same Controller.
Serve custom controller's struct's methods as handlers with custom paths(even with regex parametermized path) via the BeforeActivation
custom event callback, per-controller. Example:
import (
"github.com/kataras/iris"
"github.com/kataras/iris/mvc"
)
func main() {
app := iris.New()
mvc.Configure(app.Party("/root"), myMVC)
app.Run(iris.Addr(":8080"))
}
func myMVC(app *mvc.Application) {
// app.Register(...)
// app.Router.Use/UseGlobal/Done(...)
app.Handle(new(MyController))
}
type MyController struct {}
func (m *MyController) BeforeActivation(b mvc.BeforeActivation) {
// b.Dependencies().Add/Remove
// b.Router().Use/UseGlobal/Done // and any standard API call you already know
// 1-> Method
// 2-> Path
// 3-> The controller's function name to be parsed as handler
// 4-> Any handlers that should run before the MyCustomHandler
b.Handle("GET", "/something/{id:long}", "MyCustomHandler", anyMiddleware...)
}
// GET: http://localhost:8080/root
func (m *MyController) Get() string { return "Hey" }
// GET: http://localhost:8080/root/something/{id:long}
func (m *MyController) MyCustomHandler(id int64) string { return "MyCustomHandler says Hey" }
Persistence data inside your Controller struct (share data between requests)
by defining services to the Dependencies or have a Singleton
controller scope.
Share the dependencies between controllers or register them on a parent MVC Application, and ability
to modify dependencies per-controller on the BeforeActivation
optional event callback inside a Controller,
i.e func(c *MyController) BeforeActivation(b mvc.BeforeActivation) { b.Dependencies().Add/Remove(...) }
.
Access to the Context
as a controller's field(no manual binding is neede) i.e Ctx iris.Context
or via a method's input argument, i.e func(ctx iris.Context, otherArguments...)
.
Models inside your Controller struct (set-ed at the Method function and rendered by the View). You can return models from a controller's method or set a field in the request lifecycle and return that field to another method, in the same request lifecycle.
Flow as you used to, mvc application has its own Router
which is a type of iris/router.Party
, the standard iris api.
Controllers
can be registered to any Party
, including Subdomains, the Party's begin and done handlers work as expected.
Optional BeginRequest(ctx)
function to perform any initialization before the method execution,
useful to call middlewares or when many methods use the same collection of data.
Optional EndRequest(ctx)
function to perform any finalization after any method executed.
Inheritance, recursively, see for example our mvc.SessionController
, it has the Session *sessions.Session
and Manager *sessions.Sessions
as embedded fields
which are filled by its BeginRequest
, here.
This is just an example, you could use the sessions.Session
which returned from the manager's Start
as a dynamic dependency to the MVC Application, i.e
mvcApp.Register(sessions.New(sessions.Config{Cookie: "iris_session_id"}).Start)
.
Access to the dynamic path parameters via the controller's methods' input arguments, no binding is needed.
When you use the Iris' default syntax to parse handlers from a controller, you need to suffix the methods
with the By
word, uppercase is a new sub path. Example:
If mvc.New(app.Party("/user")).Handle(new(user.Controller))
func(*Controller) Get()
-GET:/user
.func(*Controller) Post()
-POST:/user
.func(*Controller) GetLogin()
-GET:/user/login
func(*Controller) PostLogin()
-POST:/user/login
func(*Controller) GetProfileFollowers()
-GET:/user/profile/followers
func(*Controller) PostProfileFollowers()
-POST:/user/profile/followers
func(*Controller) GetBy(id int64)
-GET:/user/{param:long}
func(*Controller) PostBy(id int64)
-POST:/user/{param:long}
If mvc.New(app.Party("/profile")).Handle(new(profile.Controller))
func(*Controller) GetBy(username string)
-GET:/profile/{param:string}
If mvc.New(app.Party("/assets")).Handle(new(file.Controller))
-
func(*Controller) GetByWildard(path string)
-GET:/assets/{param:path}
Supported types for method functions receivers: int, int64, bool and string.
Response via output arguments, optionally, i.e
func(c *ExampleController) Get() string |
(string, string) |
(string, int) |
int |
(int, string) |
(string, error) |
error |
(int, error) |
(any, bool) |
(customStruct, error) |
customStruct |
(customStruct, int) |
(customStruct, string) |
mvc.Result or (mvc.Result, error)
where mvc.Result is an interface which contains only that function: Dispatch(ctx iris.Context)
.
Using Iris MVC for code reuse
By creating components that are independent of one another, developers are able to reuse components quickly and easily in other applications. The same (or similar) view for one application can be refactored for another application with different data because the view is simply handling how the data is being displayed to the user.
If you're new to back-end web development read about the MVC architectural pattern first, a good start is that wikipedia article.
Follow the examples below,
- Hello world UPDATED
- Session Controller UPDATED
- Overview - Plus Repository and Service layers UPDATED
- Login showcase - Plus Repository and Service layers UPDATED
- Singleton NEW
- Websocket Controller NEW
- Register Middleware NEW
- Vue.js Todo MVC NEW
Subdomains
Convert http.Handler/HandlerFunc
- From func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- From http.Handler or http.HandlerFunc
- From func(http.HandlerFunc) http.HandlerFunc
View
Engine | Declaration |
---|---|
template/html | iris.HTML(...) |
django | iris.Django(...) |
handlebars | iris.Handlebars(...) |
amber | iris.Amber(...) |
pug(jade) | iris.Pug(...) |
- Overview
- Hi
- A simple Layout
- Layouts:
yield
andrender
tmpl funcs - The
urlpath
tmpl func - The
url
tmpl func - Inject Data Between Handlers
- Embedding Templates Into App Executable File
- Write to a custom
io.Writer
- Greeting with Pug (Jade)`
- Pug (Jade) Actions`
- Pug (Jade) Includes`
- Pug (Jade) Extends`
You can serve quicktemplate and hero templates files too, simply by using the context#ResponseWriter
, take a look at the http_responsewriter/quicktemplate and http_responsewriter/herotemplate examples.
Authentication
File Server
- Favicon
- Basic
- Embedding Files Into App Executable File
- Embedding Gziped Files Into App Executable File NEW
- Send/Force-Download Files
- Single Page Applications
How to Read from context.Request() *http.Request
- Read JSON
- Read XML
- Read Form
- Read Custom per type
- Read Custom via Unmarshaler
- Upload/Read File
- Upload multiple files with an easy way
- Extract referrer from "referer" header or URL query parameter NEW
The
context.Request()
returns the same *http.Request you already know, these examples show some places where the Context uses this object. Besides that you can use it as you did before iris.
How to Write to context.ResponseWriter() http.ResponseWriter
- Write
valyala/quicktemplate
templates - Write
shiyanhui/hero
templates - Text, Markdown, HTML, JSON, JSONP, XML, Binary
- Write Gzip
- Stream Writer
- Transactions
- SSE NEW
- SSE (third-party package usage for server sent events)
The
context/context#ResponseWriter()
returns an enchament version of a http.ResponseWriter, these examples show some places where the Context uses this object. Besides that you can use it as you did before iris.
ORM
Miscellaneous
- Request Logger
- Localization and Internationalization
- Recovery
- Profiling (pprof)
- Internal Application File Logger
- Google reCAPTCHA
Experimental Handlers
- Casbin wrapper
- Casbin middleware
- Cloudwatch
- CORS
- JWT
- Newrelic
- Prometheus
- Secure
- Tollboothic
- Cross-Site Request Forgery Protection
More
https://github.com/kataras/iris/tree/master/middleware#third-party-handlers
Automated API Documentation
Testing
The httptest
package is your way for end-to-end HTTP testing, it uses the httpexpect library created by our friend, gavv.
Caching
iris cache library lives on its own package.
- Simple
- Client-Side (304) - part of the iris context core
You're free to use your own favourite caching package if you'd like so.
Cookies
Sessions
iris session manager lives on its own package.
You're free to use your own favourite sessions package if you'd like so.
Websockets
iris websocket library lives on its own package.
The package is designed to work with raw websockets although its API is similar to the famous socket.io. I have read an article recently and I felt very contented about my decision to design a fast websocket-only package for Iris and not a backwards socket.io-like package. You can read that article by following this link: https://medium.com/@ivanderbyl/why-you-don-t-need-socket-io-6848f1c871cd.
You're free to use your own favourite websockets package if you'd like so.
Typescript Automation Tools
typescript automation tools have their own repository: https://github.com/kataras/iris/tree/master/typescript it contains examples
I'd like to tell you that you can use your favourite but I don't think you will find such a thing anywhere else.
Hey, You
Developers should read the godocs and https://docs.iris-go.com for a better understanding.
Psst, I almost forgot; do not forget to star or watch the project in order to stay updated with the latest tech trends, it never takes more than a second!
Directories
¶
Path | Synopsis |
---|---|
apidoc
|
|
authentication
|
|
cache
|
|
client-side
Package main shows how you can use the `WriteWithExpiration` based on the "modtime", if it's newer than the request header then it will refresh the contents, otherwise will let the client (99.9% the browser) to handle the cache mechanism, it's faster than iris.Cache because server-side has nothing to do and no need to store the responses in the memory.
|
Package main shows how you can use the `WriteWithExpiration` based on the "modtime", if it's newer than the request header then it will refresh the contents, otherwise will let the client (99.9% the browser) to handle the cache mechanism, it's faster than iris.Cache because server-side has nothing to do and no need to store the responses in the memory. |
configuration
|
|
convert-handlers
|
|
cookies
|
|
experimental-handlers
|
|
csrf
This middleware provides Cross-Site Request Forgery protection.
|
This middleware provides Cross-Site Request Forgery protection. |
jwt
iris provides some basic middleware, most for your learning curve.
|
iris provides some basic middleware, most for your learning curve. |
file-server
|
|
hero
|
|
http-listening
|
|
listen-letsencrypt
Package main provide one-line integration with letsencrypt.org
|
Package main provide one-line integration with letsencrypt.org |
http_request
|
|
read-form
package main contains an example on how to use the ReadForm, but with the same way you can do the ReadJSON & ReadJSON
|
package main contains an example on how to use the ReadForm, but with the same way you can do the ReadJSON & ReadJSON |
read-json-struct-validation
Package main shows the validator(latest, version 9) integration with Iris.
|
Package main shows the validator(latest, version 9) integration with Iris. |
http_responsewriter
|
|
herotemplate/template
Code generated by hero.
|
Code generated by hero. |
sse
Package main shows how to send continuous event messages to the clients through SSE via a broker.
|
Package main shows how to send continuous event messages to the clients through SSE via a broker. |
miscellaneous
|
|
mvc
|
|
middleware
Package main shows how you can add middleware to an mvc Application, simply by using its `Router` which is a sub router(an iris.Party) of the main iris app.
|
Package main shows how you can add middleware to an mvc Application, simply by using its `Router` which is a sub router(an iris.Party) of the main iris app. |
middleware/per-method
If you want to use it as middleware for the entire controller you can use its router which is just a sub router to add it as you normally do with standard API: I'll show you 4 different methods for adding a middleware into an mvc application, all of those 4 do exactly the same thing, select what you prefer, I prefer the last code-snippet when I need the middleware to be registered somewhere else as well, otherwise I am going with the first one: “`go // 1 mvc.Configure(app.Party("/user"), func(m *mvc.Application) { m.Router.Use(cache.Handler(10*time.Second)) }) “` “`go // 2 // same: userRouter := app.Party("/user") userRouter.Use(cache.Handler(10*time.Second)) mvc.Configure(userRouter, ...) “` “`go // 3 // same: userRouter := app.Party("/user", cache.Handler(10*time.Second)) mvc.Configure(userRouter, ...) “` “`go // 4 // same: app.PartyFunc("/user", func(r iris.Party){ r.Use(cache.Handler(10*time.Second)) mvc.Configure(r, ...) }) “` If you want to use a middleware for a single route, for a single controller's method that is already registered by the engine and not by custom `Handle` (which you can add the middleware there on the last parameter) and it's not depend on the `Next Handler` to do its job then you just call it on the method: “`go var myMiddleware := myMiddleware.New(...) // this should return an iris/context.Handler type UserController struct{} func (c *UserController) GetSomething(ctx iris.Context) { // ctx.Proceed checks if myMiddleware called `ctx.Next()` // inside it and returns true if so, otherwise false.
|
If you want to use it as middleware for the entire controller you can use its router which is just a sub router to add it as you normally do with standard API: I'll show you 4 different methods for adding a middleware into an mvc application, all of those 4 do exactly the same thing, select what you prefer, I prefer the last code-snippet when I need the middleware to be registered somewhere else as well, otherwise I am going with the first one: “`go // 1 mvc.Configure(app.Party("/user"), func(m *mvc.Application) { m.Router.Use(cache.Handler(10*time.Second)) }) “` “`go // 2 // same: userRouter := app.Party("/user") userRouter.Use(cache.Handler(10*time.Second)) mvc.Configure(userRouter, ...) “` “`go // 3 // same: userRouter := app.Party("/user", cache.Handler(10*time.Second)) mvc.Configure(userRouter, ...) “` “`go // 4 // same: app.PartyFunc("/user", func(r iris.Party){ r.Use(cache.Handler(10*time.Second)) mvc.Configure(r, ...) }) “` If you want to use a middleware for a single route, for a single controller's method that is already registered by the engine and not by custom `Handle` (which you can add the middleware there on the last parameter) and it's not depend on the `Next Handler` to do its job then you just call it on the method: “`go var myMiddleware := myMiddleware.New(...) // this should return an iris/context.Handler type UserController struct{} func (c *UserController) GetSomething(ctx iris.Context) { // ctx.Proceed checks if myMiddleware called `ctx.Next()` // inside it and returns true if so, otherwise false. |
middleware/without-ctx-next
Package main is a simple example of the behavior change of the execution flow of the handlers, normally we need the `ctx.Next()` to call the next handler in a route's handler chain, but with the new `ExecutionRules` we can change this default behavior.
|
Package main is a simple example of the behavior change of the execution flow of the handlers, normally we need the `ctx.Next()` to call the next handler in a route's handler chain, but with the new `ExecutionRules` we can change this default behavior. |
orm
|
|
xorm
Package main shows how an orm can be used within your web app it just inserts a column and select the first.
|
Package main shows how an orm can be used within your web app it just inserts a column and select the first. |
macros
Package main shows how you can register a custom parameter type and macro functions that belongs to it.
|
Package main shows how you can register a custom parameter type and macro functions that belongs to it. |
sessions
|
|
structuring
|
|
subdomains
|
|
redirect
Package main shows how to register a simple 'www' subdomain, using the `app.WWW` method, which will register a router wrapper which will redirect all 'mydomain.com' requests to 'www.mydomain.com'.
|
Package main shows how to register a simple 'www' subdomain, using the `app.WWW` method, which will register a router wrapper which will redirect all 'mydomain.com' requests to 'www.mydomain.com'. |
single
Package main register static subdomains, simple as parties, check ./hosts if you use windows
|
Package main register static subdomains, simple as parties, check ./hosts if you use windows |
wildcard
Package main an example on how to catch dynamic subdomains - wildcard.
|
Package main an example on how to catch dynamic subdomains - wildcard. |
testing
|
|
tutorial
|
|
url-shortener
Package main shows how you can create a simple URL Shortener.
|
Package main shows how you can create a simple URL Shortener. |
view
|
|
template_html_3
Package main an example on how to naming your routes & use the custom 'url path' HTML Template Engine, same for other template engines.
|
Package main an example on how to naming your routes & use the custom 'url path' HTML Template Engine, same for other template engines. |
template_html_4
Package main an example on how to naming your routes & use the custom 'url' HTML Template Engine, same for other template engines.
|
Package main an example on how to naming your routes & use the custom 'url' HTML Template Engine, same for other template engines. |
template_pug_1
Package main shows an example of pug actions based on https://github.com/Joker/jade/tree/master/example/actions
|
Package main shows an example of pug actions based on https://github.com/Joker/jade/tree/master/example/actions |
webassembly
|
|
websocket
|
|