updated example: https://github.com/kataras/iris/blob/master/_examples/i18n/main.go#L28-L50
46 KiB
Changelog
Looking for free and real-time support?
https://github.com/kataras/iris/issues
https://chat.iris-go.com
Looking for previous versions?
https://github.com/kataras/iris/releases
Want to be hired?
https://facebook.com/iris.framework
Should I upgrade my Iris?
Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready.
How to upgrade: Open your command-line and execute this command: go get github.com/kataras/iris/v12@latest.
Next
This release introduces new features and some breaking changes inside the mvc and hero packages.
The codebase for dependency injection has been simplified a lot (fewer LOCs and easier to read and follow up).
The new release contains a fresh new and awesome feature....a function dependency can accept previous registered dependencies and update or return a new value of any type.
The new implementation is faster on both design and serve-time.
The most common scenario from a route to handle is to:
- accept one or more path parameters and request data, a payload
- send back a response, a payload (JSON, XML,...)
The new Iris Dependency Injection feature is about 33.2% faster than its predecessor on the above case. This drops down even more the performance cost between native handlers and dynamic handlers with dependencies. This reason itself brings us, with safety and performance-wise, to the new Party.ConfigureContainer(builder ...func(*iris.APIContainer)) *APIContainer method which returns methods such as Handle(method, relativePath string, handlersFn ...interface{}) *Route and RegisterDependency.
Look how clean your codebase can be when using Iris':
package main
import "github.com/kataras/iris/v12"
type (
testInput struct {
Email string `json:"email"`
}
testOutput struct {
ID int `json:"id"`
Name string `json:"name"`
}
)
func handler(id int, in testInput) testOutput {
return testOutput{
ID: id,
Name: in.Email,
}
}
func main() {
app := iris.New()
app.ConfigureContainer(func(api *iris.APIContainer) {
api.Post("/{id:int}", handler)
})
app.Listen(":5000", iris.WithOptimizations)
}
Your eyes don't lie you. You read well, no ctx.ReadJSON(&v) and ctx.JSON(send) neither error handling are presented. It is a huge relief but if you ever need, you still have the control over those, even errors from dependencies. Here is a quick list of the new Party.ConfigureContainer()'s fields and methods:
// Container holds the DI Container of this Party featured Dependency Injection.
// Use it to manually convert functions or structs(controllers) to a Handler.
Container *hero.Container
// OnError adds an error handler for this Party's DI Hero Container and its handlers (or controllers).
// The "errorHandler" handles any error may occurred and returned
// during dependencies injection of the Party's hero handlers or from the handlers themselves.
OnError(errorHandler func(iris.Context, error))
// RegisterDependency adds a dependency.
// The value can be a single struct value or a function.
// Follow the rules:
// * <T> {structValue}
// * func(accepts <T>) returns <D> or (<D>, error)
// * func(accepts iris.Context) returns <D> or (<D>, error)
//
// A Dependency can accept a previous registered dependency and return a new one or the same updated.
// * func(accepts1 <D>, accepts2 <T>) returns <E> or (<E>, error) or error
// * func(acceptsPathParameter1 string, id uint64) returns <T> or (<T>, error)
//
// Usage:
//
// - RegisterDependency(loggerService{prefix: "dev"})
// - RegisterDependency(func(ctx iris.Context) User {...})
// - RegisterDependency(func(User) OtherResponse {...})
RegisterDependency(dependency interface{})
// UseResultHandler adds a result handler to the Container.
// A result handler can be used to inject the returned struct value
// from a request handler or to replace the default renderer.
UseResultHandler(handler func(next iris.ResultHandler) iris.ResultHandler)
ResultHandler
type ResultHandler func(ctx iris.Context, v interface{}) error
// Use same as a common Party's "Use" but it accepts dynamic functions as its "handlersFn" input.
Use(handlersFn ...interface{})
// Done same as a common Party's but it accepts dynamic functions as its "handlersFn" input.
Done(handlersFn ...interface{})
// Handle same as a common Party's `Handle` but it accepts one or more "handlersFn" functions which each one of them
// can accept any input arguments that match with the Party's registered Container's `Dependencies` and
// any output result; like custom structs <T>, string, []byte, int, error,
// a combination of the above, hero.Result(hero.View | hero.Response) and more.
//
// It's common from a hero handler to not even need to accept a `Context`, for that reason,
// the "handlersFn" will call `ctx.Next()` automatically when not called manually.
// To stop the execution and not continue to the next "handlersFn"
// the end-developer should output an error and return `iris.ErrStopExecution`.
Handle(method, relativePath string, handlersFn ...interface{}) *Route
// Get registers a GET route, same as `Handle("GET", relativePath, handlersFn....)`.
Get(relativePath string, handlersFn ...interface{}) *Route
// and so on...
Prior to this version the iris.Context was the only one dependency that has been automatically binded to the handler's input or a controller's fields and methods, read below to see what types are automatically binded:
| Type | Maps To |
|---|---|
| *mvc.Application | Current MVC Application |
| iris.Context | Current Iris Context |
| *sessions.Session | Current Iris Session |
| context.Context | ctx.Request().Context() |
| *http.Request | ctx.Request() |
| http.ResponseWriter | ctx.ResponseWriter() |
| http.Header | ctx.Request().Header |
| time.Time | time.Now() |
| *golog.Logger | Iris Logger |
| net.IP | net.ParseIP(ctx.RemoteAddr()) |
string, |
|
int, int8, int16, int32, int64, |
|
uint, uint8, uint16, uint32, uint64, |
|
float, float32, float64, |
|
bool, |
|
slice |
Path Parameter |
| Struct | Request Body of JSON, XML, YAML, Form, URL Query, Protobuf, MsgPack |
Here is a preview of what the new Hero handlers look like:
Request & Response & Path Parameters
1. Declare Go types for client's request body and a server's response.
type (
request struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
}
response struct {
ID uint64 `json:"id"`
Message string `json:"message"`
}
)
2. Create the route handler.
Path parameters and request body are binded automatically.
- id uint64 binds to "id:uint64"
- input request binds to client request data such as JSON
func updateUser(id uint64, input request) response {
return response{
ID: id,
Message: "User updated successfully",
}
}
3. Configure the container per group and register the route.
app.Party("/user").ConfigureContainer(container)
func container(api *iris.APIContainer) {
api.Put("/{id:uint64}", updateUser)
}
4. Simulate a client request which sends data to the server and displays the response.
curl --request PUT -d '{"firstanme":"John","lastname":"Doe"}' http://localhost:8080/user/42
{
"id": 42,
"message": "User updated successfully"
}
Custom Preflight
Before we continue to the next section, register dependencies, you may want to learn how a response can be customized through the iris.Context right before sent to the client.
The server will automatically execute the Preflight(iris.Context) error method of a function's output struct value right before send the response to the client.
Take for example that you want to fire different HTTP status codes depending on the custom logic inside your handler and also modify the value(response body) itself before sent to the client. Your response type should contain a Preflight method like below.
type response struct {
ID uint64 `json:"id,omitempty"`
Message string `json:"message"`
Code int `json:"code"`
Timestamp int64 `json:"timestamp,omitempty"`
}
func (r *response) Preflight(ctx iris.Context) error {
if r.ID > 0 {
r.Timestamp = time.Now().Unix()
}
ctx.StatusCode(r.Code)
return nil
}
Now, each handler that returns a *response value will call the response.Preflight method automatically.
func deleteUser(db *sql.DB, id uint64) *response {
// [...custom logic]
return &response{
Message: "User has been marked for deletion",
Code: iris.StatusAccepted,
}
}
If you register the route and fire a request you should see an output like this, the timestamp is filled and the HTTP status code of the response that the client will receive is 202 (Status Accepted).
{
"message": "User has been marked for deletion",
"code": 202,
"timestamp": 1583313026
}
Register Dependencies
1. Import packages to interact with a database. The go-sqlite3 package is a database driver for SQLite.
import "database/sql"
import _ "github.com/mattn/go-sqlite3"
2. Configure the container (see above), register your dependencies. Handler expects an *sql.DB instance.
localDB, _ := sql.Open("sqlite3", "./foo.db")
api.RegisterDependency(localDB)
3. Register a route to create a user.
api.Post("/{id:uint64}", createUser)
4. The create user Handler.
The handler accepts a database and some client request data such as JSON, Protobuf, Form, URL Query and e.t.c. It Returns a response.
func createUser(db *sql.DB, user request) *response {
// [custom logic using the db]
userID, err := db.CreateUser(user)
if err != nil {
return &response{
Message: err.Error(),
Code: iris.StatusInternalServerError,
}
}
return &response{
ID: userID,
Message: "User created",
Code: iris.StatusCreated,
}
}
5. Simulate a client to create a user.
# JSON
curl --request POST -d '{"firstname":"John","lastname":"Doe"}' \
--header 'Content-Type: application/json' \
http://localhost:8080/user
# Form (multipart)
curl --request POST 'http://localhost:8080/users' \
--header 'Content-Type: multipart/form-data' \
--form 'firstname=John' \
--form 'lastname=Doe'
# Form (URL-encoded)
curl --request POST 'http://localhost:8080/users' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'firstname=John' \
--data-urlencode 'lastname=Doe'
# URL Query
curl --request POST 'http://localhost:8080/users?firstname=John&lastname=Doe'
Response:
{
"id": 42,
"message": "User created",
"code": 201,
"timestamp": 1583313026
}
Other Improvements:
-
Implement feature request Log when I18n Translation Fails? by using the new
Application.I18n.DefaultMessageFuncfield beforeI18n.Load. Example of usage. -
Fix #1594 and add a new
PathAfterHandlerwhich can be set to true to enable the old behavior (not recommended though). -
New apps subpackage. Example of usage.
- Fix
AutoTLSwhen used withiris.TLSNoRedirect*. TheAutoTLSrunner can be customized through the newiris.AutoTLSNoRedirectinstead, read its go documentation. Example of having both TLS and non-TLS versions of the same application without conflicts with letsencrypt./well-knownpath:
package main
import (
"net/http"
"time"
"github.com/kataras/iris/v12"
)
func main() {
app := iris.New()
app.Logger().SetLevel("debug")
app.Get("/", func(ctx iris.Context) {
ctx.JSON(iris.Map{
"time": time.Now().Unix(),
"tls": ctx.Request().TLS != nil,
})
})
var fallbackServer = func(acme func(http.Handler) http.Handler) *http.Server {
srv := &http.Server{Handler: acme(app)}
go srv.ListenAndServe()
return srv
}
app.Run(iris.AutoTLS(":443", "example.com", "mail@example.com",
iris.AutoTLSNoRedirect(fallbackServer)))
}
-
iris.Minifymiddleware to minify responses based on their media/content-type. -
Context.OnCloseErrandContext.OnConnectionCloseErr- to call a function offunc() errorinstead of aniris.Handlerwhen request is closed or manually canceled. -
Party.UseError(...Handler)- to register handlers to run before any http errors (e.g. beforeOnErrorCode/OnAnyErrorCodeor default error codes when no handler is responsible to handle a specific http status code). -
Party.UseRouter(...Handler)- to register handlers before the main router, useful on handlers that should control whether the router itself should ran or not. Independently of the incoming request's method and path values. These handlers will be executed ALWAYS against ALL incoming matched requests. Example of use-case: CORS. -
*versioning.Grouptype is a fullPartynow. -
Party.UseOnce- either inserts a middleware, or on the basis of the middleware already existing, replace that existing middleware instead. -
Ability to register a view engine per group of routes or for the current chain of handlers through
Party.RegisterViewandContext.ViewEnginerespectfully. -
Add Blocks template engine.
-
Add Ace template parser to the view engine and other minor improvements.
-
Fix huge repo size of 55.7MB, which slows down the overall Iris installation experience. Now, go-get performs ~3 times faster. I 've managed it using the bfg-repo-cleaner tool - an alternative to git-filter-branch command. Watch the small gif below to learn how:
-
gRPC features:
- New Router Wrapper.
- New MVC
.Handle(ctrl, mvc.GRPC{...})option which allows to register gRPC services per-party (without the requirement of a full wrapper) and optionally strict access to gRPC clients only, see the example here.
-
Improved tracing (with
app.Logger().SetLevel("debug")) for routes. Example:
DBUG Routes (1)
DBUG Routes (2)
-
Add
Configuration.RemoteAddrHeadersForce boolto forceContext.RemoteAddr() stringto return the first entry of request headers as a fallback instead of theRequest.RemoteAddrone, as requested at: 1567#issuecomment-663972620. -
Fix #1564.
-
Fix #1553.
-
New
DirOptions.Cacheto cache assets in-memory among with their compressed contents (in order to be ready to served if client ask). Learn more about this feature by reading all #1556 comments. Usage:
var dirOpts = DirOptions{
// [...other options]
Cache: DirCacheOptions{
Enable: true,
// Don't compress files smaller than 300 bytes.
CompressMinSize: 300,
// Ignore compress already compressed file types
// (some images and pdf).
CompressIgnore: iris.MatchImagesAssets,
// Gzip, deflate, br(brotli), snappy.
Encodings: []string{"gzip", "deflate", "br", "snappy"},
// Log to the stdout the total reduced file size.
Verbose: 1,
},
}
- New
DirOptions.PushTargetsandPushTargetsRegexpto push index' assets to the client without additional requests. Inspirated by issue #1562. Example matching all.js, .css and .icofiles (recursively):
var dirOpts = iris.DirOptions{
// [...other options]
IndexName: "/index.html",
PushTargetsRegexp: map[string]*regexp.Regexp{
"/": regexp.MustCompile("((.*).js|(.*).css|(.*).ico)$"),
// OR:
// "/": iris.MatchCommonAssets,
},
Compress: true,
}
-
Update jet parser to v4.0.2, closes #1551. It contains two breaking changes by its author:
- Relative paths on
extends, import, include...tmpl functions, e.g.{{extends "../layouts/application.jet"}}instead oflayouts/application.jet - the new jet.Ranger interface now requires a
ProvidesIndex() boolmethod too - Example has been updated
- Relative paths on
-
Fix #1552.
-
Proper listing of root directories on
Party.HandleDirwhen itsDirOptions.ShowListwas set to true.- Customize the file/directory listing page through views, see example.
-
Socket Sharding as requested at #1544. New
iris.WithSocketShardingConfigurator andSocketSharding boolsetting. -
Versioned Controllers feature through the new
mvc.Versionoption. See _examples/mvc/versioned-controller. -
Fix #1539.
-
New rollbar example.
-
New builtin requestid middleware.
-
New builtin JWT middleware based on square/go-jose featured with optional encryption to set claims with sensitive data when necessary.
-
New
iris.RouteOverlaproute registration rule.Party.SetRegisterRule(iris.RouteOverlap)to allow overlapping across multiple routes for the same request subdomain, method, path. See 1536#issuecomment-643719922. This allows two or more MVC Controllers to listen on the same path based on one or more registered dependencies (see _examples/mvc/authenticated-controller). -
Context.ReadFormnow can return aniris.ErrEmptyForminstead ofnilwhen the newConfiguration.FireEmptyFormErroris true (wheniris.WithEmptyFormErroris set) on missing form body to read from. -
Configuration.EnablePathIntelligence | iris.WithPathIntelligenceto enable path intelligence automatic path redirection on the most closest path (if any), [example]((https://github.com/kataras/iris/blob/master/_examples/routing/intelligence/main.go) -
Enhanced cookie security and management through new
Context.AddCookieOptionsmethod and new cookie options (look on New Package-level functions section below), securecookie example has been updated. -
Context.RemoveCookieremoves also the Request's specific cookie of the same request lifecycle wheniris.CookieAllowReclaimis set to cookie options, example. -
iris.TLScan now accept certificates in form of raw[]bytecontents too. -
iris.TLSregisters a secondary http server which redirects "http://" to their "https://" equivalent requests, unless the newiris.TLSNoRedirecthost Configurator is provided oniris.TLS, e.g.app.Run(iris.TLS("127.0.0.1:443", "mycert.cert", "mykey.key", iris.TLSNoRedirect)). There isiris.AutoTLSNoRedirectoption forAutoTLStoo. -
Fix an issue about i18n loading from path which contains potential language code.
-
Server will not return neither log the
ErrServerClosederror ifapp.Shutdownwas called manually via interrupt signal(CTRL/CMD+C), note that if the server closed by any other reason the error will be fired as previously (unlessiris.WithoutServerError(iris.ErrServerClosed)). -
Finally, Log level's and Route debug information colorization is respected across outputs. Previously if the application used more than one output destination (e.g. a file through
app.Logger().AddOutput) the color support was automatically disabled from all, including the terminal one, this problem is fixed now. Developers can now see colors in their terminals while log files are kept with clear text. -
New
iris.WithLowercaseRoutingoption which forces all routes' paths to be lowercase and converts request paths to their lowercase for matching. -
New
app.Validator { Struct(interface{}) error }field andapp.Validatemethod were added. Theapp.Validator =can be used to integrate a 3rd-party package such as go-playground/validator. If set-ed then IrisContext'sReadJSON,ReadXML,ReadMsgPack,ReadYAML,ReadForm,ReadQuery,ReadBodymethods will return the validation error on data validation failures. The read-json-struct-validation example was updated. -
A result of can implement the new
hero.PreflightResultinterface which contains a single method ofPreflight(iris.Context) error. If this method exists on a custom struct value which is returned from a handler then it will fire thatPreflightfirst and if not errored then it will cotninue by sending the struct value as JSON(by-default) response body. -
ctx.JSON, JSONP, XML: ifiris.WithOptimizationsis NOT passed onapp.Run/Listenthen the indentation defaults to" "(four spaces) and" "respectfully otherwise it is empty or the provided value. -
Hero Handlers (and
app.ConfigureContainer().Handle) do not have to requireiris.Contextjust to callctx.Next()anymore, this is done automatically now. -
Improve Remote Address parsing as requested at: #1453. Add
Configuration.RemoteAddrPrivateSubnetsto exclude those addresses when fetched byConfiguration.RemoteAddrHeadersthroughcontext.RemoteAddr() string. -
Fix #1487.
-
Fix #1473.
New Package-level Variables:
iris.DirListRichOptionsto pass oniris.DirListRichmethod.iris.DirListRichto override the default look and feel if theDirOptions.ShowListwas set to true, can be passed toDirOptions.DirListfield.DirOptions.PushTargetsfor http/2 push on index *.iris.Compressionmiddleware to compress responses and decode compressed request data respectfully.iris.B, KB, MB, GB, TB, PB, EBfor byte units.TLSNoRedirectto disable automatic "http://" to "https://" redirections (see below)CookieAllowReclaim,CookieAllowSubdomains,CookieSameSite,CookieSecureandCookieEncodingto bring previously sessions-only features to all cookies in the request.
New Context Methods:
Context.ViewEngine(ViewEngine)to set a view engine on-fly for the current chain of handlers, responsible to render templates throughctx.View. Example.Context.SetErr(error)andContext.GetErr() errorhelpers.Context.CompressWriter(bool) errorandContext.CompressReader(bool) error.Context.Clone() Contextreturns a copy of the Context.Context.IsCanceled() boolreports whether the request has been canceled by the client.Context.IsSSL() boolreports whether the request is under HTTPS SSL (NewConfiguration.SSLProxyHeadersandHostProxyHeadersfields too).Context.CompressReader(enable bool)method andiris.CompressReadermiddleware to enable future request read body calls to decompress data, example.Context.RegisterDependency(v interface{})andContext.UnregisterDependency(typ reflect.Type)to register/remove struct dependencies on serve-time through a middleware.Context.SetID(id interface{})andContext.GetID() interface{}added to register a custom unique indetifier to the Context, if necessary.Context.Scheme() stringreturns the full scheme of the request URL.Context.SubdomainFull() stringreturns the full subdomain(s) part of the host (host[0:rootLevelDomain]).Context.Domain() stringreturns the root level domain.Context.AddCookieOptions(...CookieOption)adds options forSetCookie,SetCookieKV, UpsertCookieandRemoveCookiemethods for the current request.Context.ClearCookieOptions()clears any cookie options registered throughAddCookieOptions.Context.SetLanguage(langCode string)force-sets a language code from inside a middleare, similar to theapp.I18n.ExtractFuncContext.ServeContentWithRate,ServeFileWithRateandSendFileWithRatemethods to throttle the "download" speed of the clientContext.IsHTTP2() boolreports whether the protocol version for incoming request was HTTP/2Context.IsGRPC() boolreports whether the request came from a gRPC clientContext.UpsertCookie(*http.Cookie, cookieOptions ...context.CookieOption)upserts a cookie, fixes #1485 tooContext.StopWithStatus(int)stops the handlers chain and writes the status codeContext.StopWithText(int, string)stops the handlers chain, writes thre status code and a plain text messageContext.StopWithError(int, error)stops the handlers chain, writes thre status code and the error's messageContext.StopWithJSON(int, interface{})stops the handlers chain, writes the status code and sends a JSON responseContext.StopWithProblem(int, iris.Problem)stops the handlers, writes the status code and sends anapplication/problem+jsonresponseContext.Protobuf(proto.Message)sends protobuf to the client (note that theContext.JSONis able to send protobuf as JSON)Context.MsgPack(interface{})sends msgpack format data to the clientContext.ReadProtobuf(ptr)binds request body to a proto messageContext.ReadJSONProtobuf(ptr, ...options)binds JSON request body to a proto messageContext.ReadMsgPack(ptr)binds request body of a msgpack format to a structContext.ReadBody(ptr)binds the request body to the "ptr" depending on the request's Method and Content-TypeContext.ReflectValue() []reflect.Valuestores and returns the[]reflect.ValueOf(ctx)Context.Controller() reflect.Valuereturns the current MVC Controller value.
Breaking Changes:
versioning.NewGroup(string)now accepts aPartyas its first input argument:NewGroup(Party, string).versioning.RegisterGroupsis removed as it is no longer necessary.Configuration.RemoteAddrHeadersfrommap[string]boolto[]string. If you usedWith(out)RemoteAddrHeaderthen you are ready to proceed without any code changes for that one.ctx.Gzip(boolean)replaced withctx.CompressWriter(boolean) error.ctx.GzipReader(boolean) errorreplaced withctx.CompressReader(boolean) error.iris.Gzipandiris.GzipReaderreplaced withiris.Compression(middleware).ctx.ClientSupportsGzip() boolreplaced withctx.ClientSupportsEncoding("gzip", "br" ...) bool.ctx.GzipResponseWriter()is removed.Party.HandleDir/iris.FileServernow accepts ahttp.FileSysteminstead of a string and returns a list of[]*Route(GET and HEAD) instead of GET only. Write:app.HandleDir("/", iris.Dir("./assets"))instead ofapp.HandleDir("/", "./assets")andDirOptions.Asset, AssetNames, AssetInforemoved, usego-bindata -fs [..]andapp.HandleDir("/", AssetFile())instead.Context.OnCloseandContext.OnCloseConnectionnow both accept aniris.Handlerinstead of a simplefunc()as their callback.Context.StreamWriter(writer func(w io.Writer) bool)changed toStreamWriter(writer func(w io.Writer) error) errorand it's now theContext.Request().Context().Done()channel that is used to receive any close connection/manual cancel signals, instead of the deprecatedResponseWriter().CloseNotify()one. Same for theContext.OnCloseandContext.OnCloseConnectionmethods.- Fixed handler's error response not be respected when response recorder was used instead of the common writer. Fixes #1531. It contains a BREAKING CHANGE of: the new
Configuration.ResetOnFireErrorCodefield should be set to true in order to behave as it used before this update (to reset the contents on recorder). Context.String()(rarely used by end-developers) it does not return a unique string anymore, to achieve the old representation you must call the newContext.SetIDmethod first.iris.CookieEncodeandCookieDecodeare replaced with theiris.CookieEncoding.sessions#Config.EncodeandDecodeare removed in favor of (the existing)Encodingfield.versioning.GetVersionnow returns an empty string if version wasn't found.- Change the MIME type of
Javascript .jsandJSONPas the HTML specification now recommends to"text/javascript"instead of the obselete"application/javascript". This change was pushed to theGolanguage itself as well. See https://go-review.googlesource.com/c/go/+/186927/. - Remove the last input argument of
enableGzipCompressioninContext.ServeContent,ServeFilemethods. This was deprecated a few versions ago. A middleware (app.Use(iris.CompressWriter)) or a prior call toContext.CompressWriter(true)will enable compression. Also these two methods andContext.SendFileone now supportContent-RangeandAccept-Rangescorrectly out of the box (net/httphad a bug, which is now fixed). Context.ServeContentno longer returns an error, seeServeContentWithRate,ServeFileWithRateandSendFileWithRatenew methods too.route.Trace() stringchanged toroute.Trace(w io.Writer), to achieve the same result just pass abytes.Buffervar mvc.AutoBindingremoved as the default behavior now resolves such dependencies automatically (see [FEATURE REQUEST] MVC serving gRPC-compatible controller).mvc#Application.SortByNumMethods()removed as the default behavior now binds the "thinnest" emptyinterface{}automatically (see MVC: service injecting fails).mvc#BeforeActivation.Dependencies().Addshould be replaced withmvc#BeforeActivation.Dependencies().Registerinstead- REMOVE the
kataras/iris/v12/typescriptpackage in favor of the new iris-cli. Also, the alm typescript online editor was removed as it is deprecated by its author, please consider using the designtsx instead.
There is a breaking change on the type alias of iris.Context which now points to the *context.Context instead of the context.Context interface. The interface has been removed and the ability to override the Context is not available any more. When we added the ability from end-developers to override the Context years ago, we have never imagine that we will ever had such a featured Context with more than 4000 lines of code. As of Iris 2020, it is difficult and un-productive from an end-developer to override the Iris Context, and as far as we know, nobody uses this feature anymore because of that exact reason. Beside the overriding feature support end, if you still use the context.Context instead of iris.Context, it's the time to do it: please find-and-replace to iris.Context as wikis, book and all examples shows for the past 3 years. For the 99.9% of the users there is no a single breaking change, you already using iris.Context so you are in the "safe zone".
Su, 16 February 2020 | v12.1.8
New Features:
Fixes:
New Examples:
Mo, 10 February 2020 | v12.1.7
Implement new SetRegisterRule(iris.RouteOverride, RouteSkip, RouteError) to resolve: https://github.com/kataras/iris/issues/1448
New Examples:
We, 05 February 2020 | v12.1.6
Fixes:
Su, 02 February 2020 | v12.1.5
Various improvements and linting.
Su, 29 December 2019 | v12.1.4
Minor fix on serving embedded files.
We, 25 December 2019 | v12.1.3
Fix [BUG] [iris.Default] RegisterView
Th, 19 December 2019 | v12.1.2
Fix [BUG]Session works incorrectly when meets the multi-level TLDs.
Mo, 16 December 2019 | v12.1.1
Add Context.FindClosest(n int) []string
app := iris.New()
app.OnErrorCode(iris.StatusNotFound, notFound)
func notFound(ctx iris.Context) {
suggestPaths := ctx.FindClosest(3)
if len(suggestPaths) == 0 {
ctx.WriteString("404 not found")
return
}
ctx.HTML("Did you mean?<ul>")
for _, s := range suggestPaths {
ctx.HTML(`<li><a href="%s">%s</a></li>`, s, s)
}
ctx.HTML("</ul>")
}
Fr, 13 December 2019 | v12.1.0
Breaking Changes
Minor as many of you don't even use them but, indeed, they need to be covered here.
- Old i18n middleware(iris/middleware/i18n) was replaced by the i18n sub-package which lives as field at your application:
app.I18n.Load(globPathPattern string, languages ...string)(see below) - Community-driven i18n middleware(iris-contrib/middleware/go-i18n) has a
NewLoaderfunction which returns a loader which can be passed atapp.I18n.Reset(loader i18n.Loader, languages ...string)to change the locales parser - The Configuration's
TranslateFunctionContextKeywas replaced byLocaleContextKeywhich Context store's value (if i18n is used) returns the current Locale which contains the translate function, the language code, the language tag and the index position of it - The
context.Translatemethod was replaced bycontext.Tras a shortcut for the newcontext.GetLocale().GetMessage(format, args...)method and it matches the view's function{{tr format args}}too - If you used Iris Django view engine with
import _ github.com/flosch/pongo2-addonsyou must change the import path to_ github.com/iris-contrib/pongo2-addonsor add a go mod replace to yourgo.modfile, e.g.replace github.com/flosch/pongo2-addons => github.com/iris-contrib/pongo2-addons v0.0.1.
Fixes
All known issues.
New Features
Internationalization and localization
Support for i18n is now a builtin feature and is being respected across your entire application, per say sitemap and views.
Refer to the wiki section: https://github.com/kataras/iris/wiki/Sitemap for details.
Sitemaps
Iris generates and serves one or more sitemap.xml for your static routes.
Navigate through: https://github.com/kataras/iris/wiki/Sitemap for more.
New Examples
- _examples/i18n
- _examples/sitemap
- _examples/desktop/blink
- _examples/desktop/lorca
- _examples/desktop/webview
Sa, 26 October 2019 | v12.0.0
- Add version suffix of the import path, learn why and see what people voted at issue #1370
- All errors are now compatible with go1.13
errors.Is,errors.Asandfmt.Errorfand a newcore/errgrouppackage created - Fix #1383
- Report whether system couldn't find the directory of view templates
- Remove the
Party#GetReportmethod, keepParty#GetReporterwhich is anerrorand anerrgroup.Group. - Remove the router's deprecated methods such as StaticWeb and StaticEmbedded_XXX
- The
Context#CheckIfModifiedSincenow returns ancontext.ErrPreconditionFailedtype of error when client conditions are not met. Usage:if errors.Is(err, context.ErrPreconditionFailed) { ... } - Add
SourceFileNameandSourceLineNumberto theRoute, reports the exact position of its registration inside your project's source code. - Fix a bug about the MVC package route binding, see PR #1364
- Add
mvc/Application#SortByNumMethodsas requested at #1343 - Add status code
103 Early Hints - Fix performance of session.UpdateExpiration on 200 thousands+ keys with new radix as reported at issue #1328
- New redis session database configuration field:
Driver: redis.Redigo()orredis.Radix(), see updated examples - Add Clusters support for redis:radix session database (
Driver: redis:Radix()) as requested at issue #1339 - Create Iranian README_FA translation with PR #1360
- Create Korean README_KO translation with PR #1356
- Create Spanish README_ES and HISTORY_ES translations with PR #1344.
The iris-contrib/middleare and examples are updated to use the new github.com/kataras/iris/v12 import path.
Fr, 16 August 2019 | v11.2.8
- Set
Cookie.SameSitetoLaxwhen subdomains sessions share is enabled* - Add and update all experimental handlers
- New
XMLMapfunction which wraps amap[string]interface{}and converts it to a valid xml content to render throughContext.XMLmethod - Add new
ProblemOptions.XMLandRenderXMLfields to render theProblemas XML(application/problem+xml) instead of JSON("application/problem+json) and enrich theNegotiateto easily accept theapplication/problem+xmlmime.
Commit log: https://github.com/kataras/iris/compare/v11.2.7...v11.2.8
Th, 15 August 2019 | v11.2.7
This minor version contains improvements on the Problem Details for HTTP APIs implemented on v11.2.5.
- Fix https://github.com/kataras/iris/issues/1335#issuecomment-521319721
- Add
ProblemOptionswithRetryAfteras requested at: https://github.com/kataras/iris/issues/1335#issuecomment-521330994. - Add
iris.JSONalias forcontext#JSONoptions type.
References:
Commit log: https://github.com/kataras/iris/compare/v11.2.6...v11.2.7
We, 14 August 2019 | v11.2.6
app.Get("/{alias:string regexp(^[a-z0-9]{1,10}\\.xml$)}", PanoXML)
app.Get("/{alias:string regexp(^[a-z0-9]{1,10}$)}", Tour)
Commit log: https://github.com/kataras/iris/compare/v11.2.5...v11.2.6
Mo, 12 August 2019 | v11.2.5
Commit log: https://github.com/kataras/iris/compare/v11.2.4...v11.2.5
Fr, 09 August 2019 | v11.2.4
- Fixes iris.Jet: no view engine found for '.jet' or '.html'
- Fixes ctx.ViewData not work with JetEngine
- New Feature: HTTP Method Override
- Fixes Poor performance of session.UpdateExpiration on 200 thousands+ keys with new radix lib by introducing the
sessions.Config.Driverconfiguration field which defaults toRedigo()but can be set toRadix()too, future additions are welcomed.
Commit log: https://github.com/kataras/iris/compare/v11.2.3...v11.2.4
Tu, 30 July 2019 | v11.2.3
- New Feature: Handle different parameter types in the same path
- New Feature: Content Negotiation
- Context.ReadYAML
- Fixes https://github.com/kataras/neffos/issues/1#issuecomment-515698536
We, 24 July 2019 | v11.2.2
Sessions as middleware:
import "github.com/kataras/iris/v12/sessions"
// [...]
app := iris.New()
sess := sessions.New(sessions.Config{...})
app.Get("/path", func(ctx iris.Context){
session := sessions.Get(ctx)
// [work with session...]
})
- Add
Session.Len() intto return the total number of stored values/entries. - Make
Context.HTMLandContext.Textto accept an optional, variadic,args ...interface{}input arg(s) too.
v11.1.1
Tu, 23 July 2019 | v11.2.0
Read about the new release at: https://www.facebook.com/iris.framework/posts/3276606095684693






