54 KiB
History
How to upgrade: remove your $GOPATH/src/github.com/kataras
folder, open your command-line and execute this command: go get -u github.com/kataras/iris/iris
.
4.4.1 -> 4.4.5
- FIX: CORS not worked for all http methods
- FIX: Unexpected Party root's route slash when
DisablePathCorrection
is false(default), as reported here - small fix: DisablePathEscape not affects the uri string
- small fix: when Path Correction on POST redirect to the GET instead of POST
4.4.0 -> 4.4.1
- NEW: Template PreRenders, as requested here.
// ...
iris.UsePreRender(func(ctx *iris.Context, filename string, binding interface{}, options ...map[string]interface{}) bool {
// put the 'Error' binding here, for the shake of the test
if b, isMap := binding.(map[string]interface{}); isMap {
b["Error"] = "error!"
}
// true= continue to the next PreRender
// false= do not continue to the next PreRender
// * but the actual Render will be called at any case *
return true
})
iris.Get("/", func(ctx *Context) {
ctx.Render("hi.html", map[string]interface{}{"Username": "anybody"})
// hi.html: <h1>HI {{.Username}}. Error: {{.Error}}</h1>
})
// ...
4.3.0 -> 4.4.0
NOTE: For normal users this update offers nothing, read that only if you run Iris behind a proxy or balancer like nginx
or you need to serve using a custom net.Listener
.
This update implements the support of using native servers and net.Listener instead of Iris' defined.
Breaking changes
iris.Config.Profile
field removed and the whole pprof transfered to the iris-contrib/middleware/pprof.iris.ListenTLSAuto
renamed toiris.ListenLETSENCRYPT
iris.Default.Handler
isiris.Router
which is the Handler you can use to setup a custom router or bind Iris' router, afteriris.Build
call, to an external custom server.iris.ServerConfiguration
,iris.ListenVirtual
,iris.AddServer
,iris.Go
&iris.TesterConfiguration.ListeningAddr
removed, read below the reason and their alternatives
New features
- Boost Performance on server's startup
- NEW:
iris.Reserve()
re-starts the server ifiris.Close()
called previously. - NEW:
iris.Config.VHost
andiris.Config.VScheme
replaces the previousListenVirtual
,iris.TesterConfiguration.ListeningAddr
,iris.ServerConfiguration.VListeningAddr
,iris.ServerConfiguration.VScheme
. - NEW:
iris.Build
it's called automatically on Listen functions or Serve function. CALL IT, MANUALLY, ONLY WHEN YOU WANT TO BE ABLE TO GET THE IRIS ROUTER(iris.Router
) AND PASS THAT, HANDLER, TO ANOTHER EXTERNAL FASTHTTP SERVER. - NEW:
iris.Serve(net.Listener)
. Starts the server using a custom net.Listener, look below for example link - NEW: now that iris supports custom net.Listener bind, I had to provide to you some net.Listeners too, such as
iris.TCP4
,iris.UNIX
,iris.TLS
,iris.LETSENCRPYPT
&iris.CERT
, all of these are optionals because you can just use theiris.Listen
,iris.ListenUNIX
,iris.ListenTLS
&iris.ListenLETSENCRYPT
, but if you want, for example, to pass your owntls.Config
then you will have to create a custom net.Listener and pass that to theiris.Serve(net.Listener)
.
With these in mind, developers are now able to fill their advanced needs without use the iris.AddServer, ServerConfiguration and V fields
, so it's easier to:
- use any external (fasthttp compatible) server or router. Examples: server and [router]((https://github.com/iris-contrib/tree/master/custom_fasthtthttp_router)
- bind any
net.Listener
which will be used to run the Iris' HTTP server, as requested here. Example here - setup virtual host and scheme, useful when you run Iris behind
nginx
(etc) and want template function{{url }}
and subdomains to work as you expected. Usage:
iris.Config.VHost = "mydomain.com"
iris.Config.VScheme = "https://"
iris.Listen(":8080")
// this will run on localhost:8080 but templates, subdomains and all that will act like https://mydomain.com,
// before this update you used the iris.AddServer and iris.Go and pass some strange fields into
Last, for testers:
Who used the iris.ListenVirtual(...).Handler
:
If closed server, then iris.Build()
and iris.Router
, otherwise just iris.Router
.
To test subdomains or a custom domain just set the iris.Config.VHost
and iris.Config.VScheme
fields, instead of the old subdomain_test_handler := iris.AddServer(iris.ServerConfiguration{VListeningAddr:"...", Virtual: true, VScheme:false}).Handler
. Usage here.
Finally, I have to notify you that examples, plugins, middleware and book have been updated.
4.2.9 -> 4.3.0
- Align with the latest version of go-websocket, remove vendoring for compression on go-fs which produced errors on sqllite and gorm(mysql and mongo worked fine before too) as reported here.
4.2.7 -> 4.2.8 & 4.2.9
- External FIX: template syntax error causes a "template doesn't exist"
4.2.6 -> 4.2.7
- ADDED: You are now able to use a raw fasthttp handler as the router instead of the default Iris' one. Example here. But remember that I'm always recommending to use the Iris' default which supports subdomains, group of routes(parties), auto path correction and many other built'n features. This exists for specific users who told me that they need a feature like that inside Iris, we have no performance cost at all so that's ok to exists.
4.2.5 -> 4.2.6
- CHANGE: Updater (See 4.2.4 and 4.2.3) runs in its own goroutine now, unless the
iris.Config.CheckForUpdatesSync
is true. - ADDED: To align with fasthttp server's configuration, iris has these new Server Configuration's fields, which allows you to set a type of rate limit:
// Maximum number of concurrent client connections allowed per IP.
//
// By default unlimited number of concurrent connections
// may be established to the server from a single IP address.
MaxConnsPerIP int
// Maximum number of requests served per connection.
//
// The server closes connection after the last request.
// 'Connection: close' header is added to the last response.
//
// By default unlimited number of requests may be served per connection.
MaxRequestsPerConn int
// Usage: iris.ListenTo{iris.OptionServerListeningAddr(":8080"), iris.OptionServerMaxConnsPerIP(300)}
// or: iris.ListenTo(iris.ServerConfiguration{ListeningAddr: ":8080", MaxConnsPerIP: 300, MaxRequestsPerConn:100})
// for an optional second server with a different port you can always use:
// iris.AddServer(iris.ServerConfiguration{ListeningAddr: ":9090", MaxConnsPerIP: 300, MaxRequestsPerConn:100})
4.2.4 -> 4.2.5
- ADDED:
iris.CheckForUpdates(force bool)
which can run the updater(look 4.2.4) at runtime too, updater is tested and worked at dev machine.
4.2.3 -> 4.2.4
- NEW Experimental feature: Updater with a
CheckForUpdates
configuration field, as requested here
// CheckForUpdates will try to search for newer version of Iris based on the https://github.com/kataras/iris/releases
// If a newer version found then the app will ask the he dev/user if want to update the 'x' version
// if 'y' is pressed then the updater will try to install the latest version
// the updater, will notify the dev/user that the update is finished and should restart the App manually.
// Notes:
// 1. Experimental feature
// 2. If setted to true, the app will have a little startup delay
// 3. If you as developer edited the $GOPATH/src/github/kataras or any other Iris' Go dependencies at the past
// then the update process will fail.
//
// Usage: iris.Set(iris.OptionCheckForUpdates(true)) or
// iris.Config.CheckForUpdates = true or
// app := iris.New(iris.OptionCheckForUpdates(true))
// Default is false
CheckForUpdates bool
4.2.2 -> 4.2.3
4.2.1 -> 4.2.2
4.2.0 -> 4.2.1
-
CHANGE: No front-end changes if you used the default response engines before. Response Engines to Serializers,
iris.ResponseEngine
serializer.Serializer
, comes fromkataras/go-serializer
which is installed automatically when you upgrade iris with-u
flag.-
the repo "github.com/iris-contrib/response" is a clone of "github.com/kataras/go-serializer", to keep compatibility state. examples and gitbook updated to work with the last.
-
iris.UseResponse(iris.ResponseEngine, ...string)func (string)
was used to register custom response engines, now you use:iris.UseSerializer(key string, s serializer.Serializer)
. -
iris.ResponseString
same defintion but differnet name now:iris.SerializeToString
-
Serializer examples and Book section updated.
4.1.7 -> 4.2.0
- ADDED:
iris.TemplateSourceString(src string, binding interface{}) string
this will parse the src raw contents to the template engine and return the string result &context.RenderTemplateSource(status int, src string, binding interface{}, options ...map[string]interface{}) error
this will parse the src raw contents to the template engine and render the result to the client, as requseted here.
This version has 'breaking' changes if you were, directly, passing custom configuration to a custom iris instance before. As the TODO2 I had to think and implement a way to make configuration even easier and more simple to use.
With last changes in place, Iris is using new, cross-framework, and more stable packages made by me(so don't worry things are working and will as you expect) to render templates, manage sessions and websockets. So the /kataras/iris/config
is no longer need to be there, we don't have core packages inside iris which need these configuration to other package-folder than the main anymore(in order to avoid the import-cycle), new file /kataras/iris/configuration.go
is created for the configuration, which lives inside the main package, means that now:
- if you want to pass directly configuration to a new custom iris instance, you don't have to import the github.com/kataras/iris/config package
Naming changes:
config.Iris
->iris.Configuration
, which is the parent/main configuration. Added:TimeFormat
andOther
(pass any dynamic custom, other options there)config.Sessions
->iris.SessionsConfiguration
config.Websocket
->iris.WebscoketConfiguration
config.Server
->iris.ServerConfiguration
config.Tester
->iris.TesterConfiguration
All these changes wasn't made only to remove the ./config
folder but to make easier for you to pass the exact configuration field/option you need to edit at the top of the default configuration, without need to pass the whole Configuration object. Attention: old way, pass iris.Configuration
directly, is still valid object to pass to the iris.New
, so don't be afraid for breaking change, the only thing you will need to edit is the names of the configuration you saw on the previous paragraph.
Configuration Declaration:
instead of old, but still valid to pass to the iris.New
:
iris.New(iris.Configuration{Charset: "UTF-8", Sessions: iris.SessionsConfiguration{Cookie: "cookienameid"}})
now you can just write this:iris.New(iris.OptionCharset("UTF-8"), iris.OptionSessionsCookie("cookienameid"))
.New
by configuration
import "github.com/kataras/iris"
//...
myConfig := iris.Configuration{Charset: "UTF-8", IsDevelopment:true, Sessions: iris.SessionsConfiguration{Cookie:"mycookie"}, Websocket: iris.WebsocketConfiguration{Endpoint: "/my_endpoint"}}
iris.New(myConfig)
.New
by options
import "github.com/kataras/iris"
//...
iris.New(iris.OptionCharset("UTF-8"), iris.OptionIsDevelopment(true), iris.OptionSessionsCookie("mycookie"), iris.OptionWebsocketEndpoint("/my_endpoint"))
// if you want to set configuration after the .New use the .Set:
iris.Set(iris.OptionDisableBanner(true))
List of all available options:
// OptionDisablePathCorrection corrects and redirects the requested path to the registed path
// for example, if /home/ path is requested but no handler for this Route found,
// then the Router checks if /home handler exists, if yes,
// (permant)redirects the client to the correct path /home
//
// Default is false
OptionDisablePathCorrection(val bool)
// OptionDisablePathEscape when is false then its escapes the path, the named parameters (if any).
OptionDisablePathEscape(val bool)
// OptionDisableBanner outputs the iris banner at startup
//
// Default is false
OptionDisableBanner(val bool)
// OptionLoggerOut is the destination for output
//
// Default is os.Stdout
OptionLoggerOut(val io.Writer)
// OptionLoggerPreffix is the logger's prefix to write at beginning of each line
//
// Default is [IRIS]
OptionLoggerPreffix(val string)
// OptionProfilePath a the route path, set it to enable http pprof tool
// Default is empty, if you set it to a $path, these routes will handled:
OptionProfilePath(val string)
// OptionDisableTemplateEngines set to true to disable loading the default template engine (html/template) and disallow the use of iris.UseEngine
// Default is false
OptionDisableTemplateEngines(val bool)
// OptionIsDevelopment iris will act like a developer, for example
// If true then re-builds the templates on each request
// Default is false
OptionIsDevelopment(val bool)
// OptionTimeFormat time format for any kind of datetime parsing
OptionTimeFormat(val string)
// OptionCharset character encoding for various rendering
// used for templates and the rest of the responses
// Default is "UTF-8"
OptionCharset(val string)
// OptionGzip enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content
// If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true})
// Default is false
OptionGzip(val bool)
// OptionOther are the custom, dynamic options, can be empty
// this fill used only by you to set any app's options you want
// for each of an Iris instance
OptionOther(val ...options.Options) //map[string]interface{}, options is github.com/kataras/go-options
// OptionSessionsCookie string, the session's client cookie name, for example: "qsessionid"
OptionSessionsCookie(val string)
// OptionSessionsDecodeCookie set it to true to decode the cookie key with base64 URLEncoding
// Defaults to false
OptionSessionsDecodeCookie(val bool)
// OptionSessionsExpires the duration of which the cookie must expires (created_time.Add(Expires)).
// If you want to delete the cookie when the browser closes, set it to -1 but in this case, the server side's session duration is up to GcDuration
//
// Default infinitive/unlimited life duration(0)
OptionSessionsExpires(val time.Duration)
// OptionSessionsCookieLength the length of the sessionid's cookie's value, let it to 0 if you don't want to change it
// Defaults to 32
OptionSessionsCookieLength(val int)
// OptionSessionsGcDuration every how much duration(GcDuration) the memory should be clear for unused cookies (GcDuration)
// for example: time.Duration(2)*time.Hour. it will check every 2 hours if cookie hasn't be used for 2 hours,
// deletes it from backend memory until the user comes back, then the session continue to work as it was
//
// Default 2 hours
OptionSessionsGcDuration(val time.Duration)
// OptionSessionsDisableSubdomainPersistence set it to true in order dissallow your q subdomains to have access to the session cookie
// defaults to false
OptionSessionsDisableSubdomainPersistence(val bool)
// OptionWebsocketWriteTimeout time allowed to write a message to the connection.
// Default value is 15 * time.Second
OptionWebsocketWriteTimeout(val time.Duration)
// OptionWebsocketPongTimeout allowed to read the next pong message from the connection
// Default value is 60 * time.Second
OptionWebsocketPongTimeout(val time.Duration)
// OptionWebsocketPingPeriod send ping messages to the connection with this period. Must be less than PongTimeout
// Default value is (PongTimeout * 9) / 10
OptionWebsocketPingPeriod(val time.Duration)
// OptionWebsocketMaxMessageSize max message size allowed from connection
// Default value is 1024
OptionWebsocketMaxMessageSize(val int64)
// OptionWebsocketBinaryMessages set it to true in order to denotes binary data messages instead of utf-8 text
// see https://github.com/kataras/iris/issues/387#issuecomment-243006022 for more
// defaults to false
OptionWebsocketBinaryMessages(val bool)
// OptionWebsocketEndpoint is the path which the websocket server will listen for clients/connections
// Default value is empty string, if you don't set it the Websocket server is disabled.
OptionWebsocketEndpoint(val string)
// OptionWebsocketReadBufferSize is the buffer size for the underline reader
OptionWebsocketReadBufferSize(val int)
// OptionWebsocketWriteBufferSize is the buffer size for the underline writer
OptionWebsocketWriteBufferSize(val int)
// OptionTesterListeningAddr is the virtual server's listening addr (host)
// Default is "iris-go.com:1993"
OptionTesterListeningAddr(val string)
// OptionTesterExplicitURL If true then the url (should) be prepended manually, useful when want to test subdomains
// Default is false
OptionTesterExplicitURL(val bool)
// OptionTesterDebug if true then debug messages from the httpexpect will be shown when a test runs
// Default is false
OptionTesterDebug(val bool)
Now, some of you maybe use more than one server inside their iris instance/app, so you used the iris.AddServer(config.Server{})
, which now becomes iris.AddServer(iris.ServerConfiguration{})
, ServerConfiguration has also (optional) options to pass there and to iris.ListenTo(OptionServerListeningAddr("mydomain.com"))
:
// examples:
iris.AddServer(iris.OptionServerCertFile("file.cert"),iris.OptionServerKeyFile("file.key"))
iris.ListenTo(iris.OptionServerReadBufferSize(42000))
// or, old way but still valid:
iris.AddServer(iris.ServerConfiguration{ListeningAddr: "mydomain.com", CertFile: "file.cert", KeyFile: "file.key"})
iris.ListenTo(iris.ServerConfiguration{ReadBufferSize:42000, ListeningAddr: "mydomain.com"})
List of all Server's options:
OptionServerListeningAddr(val string)
OptionServerCertFile(val string)
OptionServerKeyFile(val string)
// AutoTLS enable to get certifications from the Letsencrypt
// when this configuration field is true, the CertFile & KeyFile are empty, no need to provide a key.
//
// example: https://github.com/iris-contrib/examples/blob/master/letsencyrpt/main.go
OptionServerAutoTLS(val bool)
// Mode this is for unix only
OptionServerMode(val os.FileMode)
// OptionServerMaxRequestBodySize Maximum request body size.
//
// The server rejects requests with bodies exceeding this limit.
//
// By default request body size is 8MB.
OptionServerMaxRequestBodySize(val int)
// Per-connection buffer size for requests' reading.
// This also limits the maximum header size.
//
// Increase this buffer if your clients send multi-KB RequestURIs
// and/or multi-KB headers (for example, BIG cookies).
//
// Default buffer size is used if not set.
OptionServerReadBufferSize(val int)
// Per-connection buffer size for responses' writing.
//
// Default buffer size is used if not set.
OptionServerWriteBufferSize(val int)
// Maximum duration for reading the full request (including body).
//
// This also limits the maximum duration for idle keep-alive
// connections.
//
// By default request read timeout is unlimited.
OptionServerReadTimeout(val time.Duration)
// Maximum duration for writing the full response (including body).
//
// By default response write timeout is unlimited.
OptionServerWriteTimeout(val time.Duration)
// RedirectTo, defaults to empty, set it in order to override the station's handler and redirect all requests to this address which is of form(HOST:PORT or :PORT)
//
// NOTE: the http status is 'StatusMovedPermanently', means one-time-redirect(the browser remembers the new addr and goes to the new address without need to request something from this server
// which means that if you want to change this address you have to clear your browser's cache in order this to be able to change to the new addr.
//
// example: https://github.com/iris-contrib/examples/tree/master/multiserver_listening2
OptionServerRedirectTo(val string)
// OptionServerVirtual If this server is not really listens to a real host, it mostly used in order to achieve testing without system modifications
OptionServerVirtual(val bool)
// OptionServerVListeningAddr, can be used for both virtual = true or false,
// if it's setted to not empty, then the server's Host() will return this addr instead of the ListeningAddr.
// server's Host() is used inside global template helper funcs
// set it when you are sure you know what it does.
//
// Default is empty ""
OptionServerVListeningAddr(val string)
// OptionServerVScheme if setted to not empty value then all template's helper funcs prepends that as the url scheme instead of the real scheme
// server's .Scheme returns VScheme if not empty && differs from real scheme
//
// Default is empty ""
OptionServerVScheme(val string)
// OptionServerName the server's name, defaults to "iris".
// You're free to change it, but I will trust you to don't, this is the only setting whose somebody, like me, can see if iris web framework is used
OptionServerName(val string)
View all configuration fields and options by navigating to the kataras/iris/configuration.go source file
Book & Examples are updated (website docs will be updated soon).
4.1.6 -> 4.1.7
- CHANGED: Use of the standard
log.Logger
instead of theiris-contrib/logger
(colorful logger), these changes are reflects some middleware, examples and plugins, I updated all of them, so don't worry.
So, iris-contrib/middleware/logger will now NO need to pass other Logger instead, instead of: iris.Use(logger.New(iris.Logger))
use -> iris.Use(logger.New())
which will use the iris/instance's Logger.
- ADDED:
context.Framework()
which returns your Iris instance (typeof*iris.Framework
), useful for the future(Iris will give you, soon, the ability to pass custom options inside an iris instance).
4.1.5 -> 4.1.6
- Align with go-sessions, no front-end changes, however I think that the best time to make an upgrade to your local Iris is right now.
4.1.4 -> 4.1.5
- Remove unused Plugin's custom callbacks, if you still need them in your project use this instead: https://github.com/kataras/go-events
4.1.3 -> 4.1.4
Zero front-end changes. No real improvements, developers can ignore this update.
-
Replace the iris sessions with a new cross-framework package, go-sessions. Same front-end API, sessions examples are compatible, configuration of
kataras/iris/config/sessions.go
is compatible.kataras/context.SessionStore
is nowkataras/go-sessions.Session
(normally you, as user, never used it before, because of automatically session getting bycontext.Session()
) -
GzipWriter
is taken, now, from thekataras/go-fs
package which has improvements versus the previous implementation.
4.1.2 -> 4.1.3
Zero front-end changes. No real improvements, developers can ignore this update.
- Replace the template engines with a new cross-framework package, go-template. Same front-end API, examples and iris-contrib/template are compatible.
4.1.1 -> 4.1.2
Zero front-end changes. No real improvements, developers can ignore this update.
- Replace the main and underline websocket implementation with go-websocket. Note that we still need the ris-contrib/websocket package.
- Replace the use of iris-contrib/errors with go-errors, which has more features
4.0.0 -> 4.1.1
- NEW FEATURE: Basic remote control through SSH, example here
- NEW FEATURE: Optionally
OnError
foreach Party (by prefix, use it with your own risk), example here - NEW:
iris.Config.Sessions.CookieLength
, You're able to customize the length of each sessionid's cookie's value. Default (and previous' implementation) is 32. - FIX: Websocket panic on non-websocket connection*
- FIX: Multi websocket servers client-side source route panic*
- Better gzip response managment
4.0.0-alpha.5 -> 4.0.0
-
Feature request has been implemented: Add layout support for Pug/Jade, example here.
-
Feature request has been implemented: Forcefully closing a Websocket connection,
WebsocketConnection.Disconnect() error
. -
FIX: WebsocketConnection.Leave() will hang websocket server if .Leave was called manually when the websocket connection has been closed.
-
FIX: StaticWeb not serving index.html correctly, align the func with the rest of Static funcs also, example added.
Notes: if you compare it with previous releases (13+ versions before v3 stable), the v4 stable release was fast, now we had only 6 versions before stable, that was happened because many of bugs have been already fixed and we hadn't new bug reports and secondly, and most important for me, some third-party features are implemented mostly by third-party packages via other developers!
4.0.0-alpha.4 -> 4.0.0-alpha.5
- NEW FEATURE: Letsencrypt.org integration*
- example here
- FIX: (ListenUNIX adds :80 to filename)[https://github.com/kataras/iris/issues/321]
- FIX: (Go-Bindata + ctx.Render)[https://github.com/kataras/iris/issues/315]
- FIX (auto-gzip doesn't really compress data in latest code)[https://github.com/kataras/iris/issues/312]
4.0.0-alpha.3 -> 4.0.0-alpha.4
The important , is that the book is finally updated!
If you're willing to donate click here!
-
iris.Config.Gzip
, enables gzip compression on your Render actions, this includes any type of render, templates and pure/raw content. If you don't want to enable it globaly, you could just use the third parameter on context.Render("myfileOrResponse", structBinding{}, iris.RenderOptions{"gzip": true}). It defaults to false -
Added
config.Server.Name
as requested
Fix
**Sessions changes **
iris.Config.Sessions.Expires
it was time.Time, changed to time.Duration, which defaults to 0, means unlimited session life duration, if you change it then the correct date is setted on client's cookie but also server destroys the session automatically when the duration passed, this is better approach, see here
4.0.0-alpha.2 -> 4.0.0-alpha.3
New
A Response Engine gives you the freedom to create/change the render/response writer for
context.JSON
context.JSONP
context.XML
context.Text
context.Markdown
context.Data
context.Render("my_custom_type",mystructOrData{}, iris.RenderOptions{"gzip":false,"charset":"UTF-8"})
context.MarkdownString
iris.ResponseString(...)
Fix
Small changes
iris.Config.Charset
, before alpha.3 wasiris.Config.Rest.Charset
&iris.Config.Render.Template.Charset
, but you can override it at runtime by passinth a mapiris.RenderOptions
on thecontext.Render
call .iris.Config.IsDevelopment
, before alpha.1 wasiris.Config.Render.Template.IsDevelopment
Websockets changes
No need to import the github.com/kataras/iris/websocket
to use the Connection
iteral, the websocket moved inside kataras/iris
, now all exported variables' names have the prefix of Websocket
, so the old websocket.Connection
is now iris.WebsocketConnection
.
Generally, no other changes on the 'frontend API', for response engines examples and how you can register your own to add more features on existing response engines or replace them, look here.
BAD SIDE: E-Book is still pointing on the v3 release, but will be updated soon.
4.0.0-alpha.1 -> 4.0.0-alpha.2
**Sessions were re-written **
- Developers can use more than one 'session database', at the same time, to store the sessions
- Easy to develop a custom session database (only two functions are required (Load & Update)), learn more
- Session databases are located here, contributions are welcome
- The only frontend deleted 'thing' is the: config.Sessions.Provider
- No need to register a database, the sessions works out-of-the-box
- No frontend/API changes except the
context.Session().Set/Delete/Clear
, they doesn't return errors anymore, btw they (errors) were always nil :) - Examples (master branch) were updated.
$ go get github.com/iris-contrib/sessiondb/$DATABASE
db := $DATABASE.New(configurationHere{})
iris.UseSessionDB(db)
Note: Book is not updated yet, examples are up-to-date as always.
3.0.0 -> 4.0.0-alpha.1
logger, rest and all template engines moved to the iris-contrib.
-
config.Logger
->iris.Logger.Config
-
config.Render/config.Render.Rest/config.Render.Template
-> Removed -
config.Render.Rest
->rest.Config
-
config.Render.Template
->$TEMPLATE_ENGINE.Config
except Directory,Extensions, Assets, AssetNames, -
config.Render.Template.Directory
->iris.UseTemplate($TEMPLAET_ENGINE.New()).Directory("./templates", ".html")
-
config.Render.Template.Assets
->iris.UseTemplate($TEMPLAET_ENGINE.New()).Directory("./templates",".html").Binary(assetFn func(name string) ([]byte, error), namesFn func() []string)
-
context.ExecuteTemplate
-> Removed, you can use thecontext.Response.BodyWriter()
to get its writer and execute html/template engine manually, but this is useless because we support the best support for template engines among all other (golang) web frameworks -
Added
config.Server.ReadBufferSize & config.Server.WriteBufferSize
which can be passed as configuration fields insideiris.ListenTo(config.Server{...})
, which does the same job asiris.Listen
-
Added
iris.UseTemplate($TEMPLAET_ENGINE.New()).Directory("./templates", ".html")
to register a template engine, now iris supports multi template engines, each template engine has its own file extension, no big changes on context.Render except the last parameter: -
context.Render(filename string, binding interface{}, layout string{})
->context.Render(filename string, binding interface{}, options ...map[string]interface{}) | context.Render("myfile.html", myPage{}, iris.Map{"gzip":true,"layout":"layouts/MyLayout.html"}) |
E-book and examples are not yet updated, no big changes.
3.0.0-rc.4 -> 3.0.0-pre.release
-
context.PostFormValue
->context.FormValueString
, old func stays until the next revision -
context.PostFormMulti
->context.FormValues
, old func stays until the next revision -
Added
context.VisitAllCookies(func(key,value string))
to visit all your cookies (becausecontext.Request.Header.VisitAllCookie
has a bug(I can't fix/pr it because the author is away atm)) -
Added
context.GetFlashes
to get all available flash messages for a particular request -
Fix flash message removed after the first
GetFlash
call in the same request
NEW FEATURE: Built'n support for multi listening servers per iris station, secondary and virtual servers with one-line using the iris.AddServer
& iris.Go
to start all servers.
iris.SecondaryListen
->iris.AddServer
, old func stays until the next revision- Added
iris.Servers
with this field you can manage your servers very easy - Added
iris.AddServer/iris.ListenTo/iris.Go
, but funcs likeListen/ListenTLS/ListenUNIX
will stay forever - Added
config.Server.Virtual(bool), config.Server.RedirectTo(string) and config.Server.MaxRequestBodySize(int64)
- Added
iris.Available (channel bool)
iris.HTTPServer
->iris.Servers.Main()
to get the main server, which is always the last registered server (if more than one used), old field removediris.Config.MaxRequestBodySize
->config.Server.MaxRequestBodySize
, old field removed
NEW FEATURE: Build'n support for your API's end-to-end tests
- Added
tester := iris.Tester(*testing.T)
, look inside: http_test.go & ./context_test.go forTester
usage, you can also look inside the httpexpect's repo for extended examples with Iris.
3.0.0-rc.3 -> 3.0.0-rc.4
NEW FEATURE: Handlebars template engine support with all Iris' view engine's functions/helpers support, as requested here:
iris.Config.Render.Template.Layout = "layouts/layout.html"
config.NoLayout
- dynamic optional layout on
context.Render
- Party specific layout
iris.Config.Render.Template.Handlebars.Helpers["myhelper"] = func()...
{{ yield }}
{{ render }}
{{ url "myroute" myparams}}
{{ urlpath "myroute" myparams}}
For a complete example please, click here.
NEW: Iris can listen to more than one server per station now, as requested here. For example you can have https with SSL/TLS and one more server http which navigates to the secure location. Take a look here for an example of this.
FIXES
- Fix
sessions destroy
- Fix
sessions persistence on subdomains
(as RFC2109 commands but you can disable it withiris.Config.Sessions.DisableSubdomainPersistence = true
)
IMPROVEMENTS
- Improvements on
iris run
&&iris create
, note that the underline code for hot-reloading moved to rizla.
3.0.0-rc.2 -> 3.0.0-rc.3
Breaking changes
- Move middleware & their configs to the iris-contrib/middleware repository
- Move all plugins & their configs to the iris-contrib/plugin repository
- Move the graceful package to the iris-contrib/graceful repository
- Move the mail package & its configs to the iris-contrib/mail repository
Note 1: iris.Config.Mail doesn't not logger exists, use mail.Config
from the iris-contrib/mail
, and service:= mail.New(configs); service.Send(....)
.
Note 2: basicauth middleware's context key changed from context.GetString("auth")
to context.GetString("user")
.
Underline changes, libraries used by iris' base code:
- Move the errors package to the iris-contrib/errors repository
- Move the tests package to the iris-contrib/tests repository (Yes, you should make PRs now with no fear about breaking the Iris).
NEW:
-
OAuth, OAuth2 support via plugin (facebook,gplus,twitter and 25 more), gitbook section here, plugin example, low-level package example here (no performance differences, it's just a working version of goth which is converted to work with Iris)
-
JSON Web Tokens support via this middleware, book section here, as requested here.
Fixes:
Improvements to the iris run
command, as requested here.
Book and examples are updated also.
3.0.0-rc.1 -> 3.0.0-rc.2
New:
iris.MustUse/MustUseFunc
- registers middleware for all route parties, all subdomains and all routes.- iris control plugin re-written, added real time browser request logger
websocket.OnError
- Add OnError to be able to catch internal errors from the connection- command line tool -
iris run main.go
runs, watch and reload on source code changes. As requested here
Fixes: https://github.com/kataras/iris/issues/184 , https://github.com/kataras/iris/issues/175 .
3.0.0-beta.3, 3.0.0-beta.4 -> 3.0.0-rc.1
This version took me many days because the whole framework's underline code is rewritten after many many many 'yoga'. Iris is not so small anymore, so I (tried) to organized it a little better. Note that, today, you can just go to iris.go and context.go and look what functions you can use. You had some 'bugs' to subdomains, mail service, basic authentication and logger, these are fixed also, see below...
All examples are updated, and I tested them one by one.
Many underline changes but the public API didn't changed much, of course this is relative to the way you use this framework, because that:
-
Configuration changes: 0
-
iris.Iris pointer -> iris.Framework pointer
-
iris.DefaultIris -> iris.Default
-
iris.Config() -> iris.Config is field now
-
iris.Websocket() -> iris.Websocket is field now
-
iris.Logger() -> iris.Logger is field now
-
iris.Plugins() -> iris.Plugins is field now
-
iris.Server() -> iris.HTTPServer is field now
-
iris.Rest() -> REMOVED
-
iris.Mail() -> REMOVED
-
iris.Mail().Send() -> iris.SendMail()
-
iris.Templates() -> REMOVED
-
iris.Templates().RenderString() -> iris.TemplateString()
-
iris.StaticHandlerFunc -> iris.StaticHandler
-
iris.URIOf() -> iris.URL()
-
iris.PathOf() -> iris.Path()
-
context.RenderString() returned string,error -> context.TemplateString() returns only string, which is empty on any parse error
-
context.WriteHTML() -> context.HTML()
-
context.HTML() -> context.RenderWithStatus()
Entirely new
-
-> iris.ListenUNIX(addr string, socket os.Mode)
-
-> context.MustRender, same as Render but send response 500 and logs the error on parse error
-
-> context.Log(format string, a...interface{})
-
-> context.PostFormMulti(name string) []string
-
-> iris.Lookups() []Route
-
-> iris.Lookup(routeName string) Route
-
-> iris.Plugins.On(eventName string, ...func()) and fire all by iris.Plugins.Call(eventName)
-
iris.Wildcard() REMOVED, subdomains and dynamic(wildcard) subdomains can only be registered with iris.Party("mysubdomain.") && iris.Party("*.")
Semantic change for static subdomains
1
BEFORE :
apiSubdomain := iris.Party("api.mydomain.com")
{
//....
}
iris.Listen("mydomain.com:80")
NOW just subdomain part, no need to duplicate ourselves:
apiSubdomain := iris.Party("api.")
{
//....
}
iris.Listen("mydomain.com:80")
2
Before you couldn't set dynamic subdomains and normal subdomains at the same iris station, now you can. NOW, this is possible
/* admin.mydomain.com, and for other subdomains the Party(*.) */
admin := iris.Party("admin.")
{
// admin.mydomain.com
admin.Get("/", func(c *iris.Context) {
c.Write("INDEX FROM admin.mydomain.com")
})
// admin.mydomain.com/hey
admin.Get("/hey", func(c *iris.Context) {
c.Write("HEY FROM admin.mydomain.com/hey")
})
// admin.mydomain.com/hey2
admin.Get("/hey2", func(c *iris.Context) {
c.Write("HEY SECOND FROM admin.mydomain.com/hey")
})
}
// other.mydomain.com, otadsadsadsa.mydomain.com and so on....
dynamicSubdomains := iris.Party("*.")
{
dynamicSubdomains.Get("/", dynamicSubdomainHandler)
dynamicSubdomains.Get("/something", dynamicSubdomainHandler)
dynamicSubdomains.Get("/something/:param1", dynamicSubdomainHandlerWithParam)
}
Minor change for listen
BEFORE you could just listen to a port
iris.Listen("8080")
NOW you have set a HOSTNAME:PORT
iris.Listen(":8080")
Relative issues/features: https://github.com/kataras/iris/issues/166 , https://github.com/kataras/iris/issues/176, https://github.com/kataras/iris/issues/183, https://github.com/kataras/iris/issues/184
Plugins
PreHandle and PostHandle are removed, no need to use them anymore you can take routes by iris.Lookups(), but add support for custom event listeners by iris.Plugins.On("event",func(){}) and fire all callbacks by iris.Plugins.Call("event") .
FOR TESTERS
BEFORE :
api := iris.New()
//...
api.PreListen(config.Server{ListeningAddr: ""})
e := httpexpect.WithConfig(httpexpect.Config{
Reporter: httpexpect.NewAssertReporter(t),
Client: fasthttpexpect.NewBinder(api.ServeRequest),
})
NOW:
api := iris.New()
//...
e := httpexpect.WithConfig(httpexpect.Config{
Reporter: httpexpect.NewAssertReporter(t),
Client: fasthttpexpect.NewBinder(api.NoListen().Handler),
})
3.0.0-beta.2 -> 3.0.0-beta.3
-
Complete the Jade Template Engine support, {{ render }} and {{ url }} done also.
-
Fix Mail().Send
-
Iriscontrol plugin: Replace login using session to basic authentication
And other not-too-important fixes
3.0.0-beta -> 3.0.0-beta.2
-
NEW: Wildcard(dynamic) subdomains, read here
-
NEW: Implement feature request #165. Routes can now be selected by
a custom name
, and this allows us to use the {{ url "custom-name" "any" "named" "parameters"}}``: For HTML & Amber engines, example here. For PongoEngine, example here -
Remove the x/net/context, it has been useless after v2.
3.0.0-alpha.beta -> 3.0.0-beta
-
New iris.API for easy API declaration, read more here, example there.
-
Add example and fix the Basic Authentication middleware
3.0.0-alpha.6 -> 3.0.0-alpha.beta
-
Implement a unique easy only-websocket support:
OnConnection(func(c websocket.Connection){})
websocket.Connection
// Receive from the client
On("anyCustomEvent", func(message string) {})
On("anyCustomEvent", func(message int){})
On("anyCustomEvent", func(message bool){})
On("anyCustomEvent", func(message anyCustomType){})
On("anyCustomEvent", func(){})
// Receive a native websocket message from the client
// compatible without need of import the iris-ws.js to the .html
OnMessage(func(message []byte){})
// Send to the client
Emit("anyCustomEvent", string)
Emit("anyCustomEvent", int)
Emit("anyCustomEvent", bool)
Emit("anyCustomEvent", anyCustomType)
// Send via native websocket way, compatible without need of import the iris-ws.js to the .html
EmitMessage([]byte("anyMessage"))
// Send to specific client(s)
To("otherConnectionId").Emit/EmitMessage...
To("anyCustomRoom").Emit/EmitMessage...
// Send to all opened connections/clients
To(websocket.All).Emit/EmitMessage...
// Send to all opened connections/clients EXCEPT this client(c)
To(websocket.NotMe).Emit/EmitMessage...
// Rooms, group of connections/clients
Join("anyCustomRoom")
Leave("anyCustomRoom")
// Fired when the connection is closed
OnDisconnect(func(){})
We have some base-config's changed, these configs which are defaulted to true renamed to 'Disable+$oldName'
// DisablePathCorrection corrects and redirects the requested path to the registed path
// for example, if /home/ path is requested but no handler for this Route found,
// then the Router checks if /home handler exists, if yes,
// (permant)redirects the client to the correct path /home
//
// Default is false
DisablePathCorrection bool
// DisablePathEscape when is false then its escapes the path, the named parameters (if any).
// Change to true it if you want something like this https://github.com/kataras/iris/issues/135 to work
//
// When do you need to Disable(true) it:
// accepts parameters with slash '/'
// Request: http://localhost:8080/details/Project%2FDelta
// ctx.Param("project") returns the raw named parameter: Project%2FDelta
// which you can escape it manually with net/url:
// projectName, _ := url.QueryUnescape(c.Param("project").
// Look here: https://github.com/kataras/iris/issues/135 for more
//
// Default is false
DisablePathEscape bool
// DisableLog turn it to true if you want to disable logger,
// Iris prints/logs ONLY errors, so be careful when you enable it
DisableLog bool
// DisableBanner outputs the iris banner at startup
//
// Default is false
DisableBanner bool
3.0.0-alpha.5 -> 3.0.0-alpha.6
Changes:
- config/iris.Config().Render.Template.HTMLTemplate.Funcs typeof []template.FuncMap
-> template.FuncMap
Added: - iris.AmberEngine Amber. View an example - iris.JadeEngine Jade. View an example
Book section Render/Templates updated
3.0.0-alpha.4 -> 3.0.0-alpha.5
- NoLayout support for particular templates
- Raw Markdown Template Engine
- Markdown to HTML >
context.Markdown(statusCode int, markdown string)
,context.MarkdownString(markdown string) (htmlReturn string)
- Simplify the plugin registration
3.0.0-alpha.3 -> 3.0.0-alpha.4
Community suggestions implemented:
- Request: Rendering html template to string
New RenderString(name string, binding interface{}, layout ...string) added to the Context & the Iris' station (iris.Templates().RenderString)
- Minify Templates
New config field for minify, defaulted to true: iris.Config().Render.Template.Minify = true 3.0.0-alpha5+ this has been removed because the minify package has bugs, one of them is this: https://github.com/tdewolff/minify/issues/35.
Bugfixes and enhancements:
3.0.0-alpha.2 -> 3.0.0-alpha.3
The only change here is a panic-fix on form bindings. Now no need to make([]string,0) before form binding, new example:
//./main.go
package main
import (
"fmt"
"github.com/kataras/iris"
)
type Visitor struct {
Username string
Mail string
Data []string `form:"mydata"`
}
func main() {
iris.Get("/", func(ctx *iris.Context) {
ctx.Render("form.html", nil)
})
iris.Post("/form_action", func(ctx *iris.Context) {
visitor := Visitor{}
err := ctx.ReadForm(&visitor)
if err != nil {
fmt.Println("Error when reading form: " + err.Error())
}
fmt.Printf("\n Visitor: %v", visitor)
})
fmt.Println("Server is running at :8080")
iris.Listen(":8080")
}
<!-- ./templates/form.html -->
<!DOCTYPE html>
<head>
<meta charset="utf-8">
</head>
<body>
<form action="/form_action" method="post">
<input type="text" name="Username" />
<br/>
<input type="text" name="Mail" /><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>
3.0.0-alpha.1 -> 3.0.0-alpha.2
The e-book was updated, take a closer look here
Breaking changes
First. Configuration owns a package now github.com/kataras/iris/config
. I took this decision after a lot of thought and I ensure you that this is the best
architecture to easy:
-
change the configs without need to re-write all of their fields.
irisConfig := config.Iris { Profile: true, PathCorrection: false } api := iris.New(irisConfig)
-
easy to remember:
iris
type takes config.Iris, sessions takes config.Sessions,
iris.Config().Renderis
config.Render,
iris.Config().Render.Templateis
config.Template,
Loggertakes
config.Logger` and so on... -
easy to find what features are exists and what you can change: just navigate to the config folder and open the type you want to learn about, for example
/iris.go
Iris' type configuration is on/config/iris.go
-
default setted fields which you can use. They are already setted by iris, so don't worry too much, but if you ever need them you can find their default configs by this pattern: for example
config.Template
hasconfig.DefaultTemplate()
,config.Rest
hasconfig.DefaultRest()
,config.Typescript()
hasconfig.DefaultTypescript()
, note that onlyconfig.Iris
hasconfig.Default()
. I wrote that all structs even the plugins have their default configs now, to make it easier for you, so you can do this without set a config by yourself:iris.Config().Render.Template.Engine = config.PongoEngine
oriris.Config().Render.Template.Pongo.Extensions = []string{".xhtml", ".html"}
.
Second. Template & rest package moved to the render
, so
* a new config field named `render` of type `config.Render` which nests the `config.Template` & `config.Rest`
- `iris.Config().Templates` -> `iris.Config().Render.Template` of type `config.Template`
- `iris.Config().Rest` -> `iris.Config().Render.Rest` of type `config.Rest`
Third, sessions.
Configuration instead of parameters. Before sessions.New("memory","sessionid",time.Duration(42) * time.Minute)
-> Now: sessions.New(config.DefaultSessions())
of type config.Sessions
-
Before this change the cookie's life was the same as the manager's Gc duration. Now added an Expires option for the cookie's life time which defaults to infinitive, as you (correctly) suggests me in the chat community.-
-
Default Cookie's expiration date: from 42 minutes -> to
infinitive/forever
-
Manager's Gc duration: from 42 minutes -> to '2 hours'
-
Redis store's MaxAgeSeconds: from 42 minutes -> to '1 year`
Four. Typescript, Editor & IrisControl plugins now accept a config.Typescript/ config.Editor/ config.IrisControl as parameter
Bugfixes
- can't open /xxx/ path when PathCorrection = false
- Invalid content on links on debug page when custom ProfilePath is set
- Example with custom config not working
- Debug Profiler writing escaped HTML?
- CORS middleware doesn't work
2.3.2 -> 3.0.0-alpha.1
Changed
-
&render.Config
->&iris.RestConfig
. All related to the html/template are removed from there. -
ctx.Render("index",...)
->ctx.Render("index.html",...)
or any extension you have defined in iris.Config().Templates.Extensions -
iris.Config().Render.Layout = "layouts/layout"
->iris.Config().Templates.Layout = "layouts/layout.html"
-
License BSD-3 Clause Open source
->MIT License
Added -
Switch template engines via
IrisConfig
. Currently, HTMLTemplate is 'html/template'. Pongo is 'flosch/pongo2`. Refer to the Book, which is updated too, read here.