mirror of
https://github.com/kataras/iris.git
synced 2025-03-14 08:16:28 +01:00
sync with master fixes and add more details in the HISTORY.md for the upcoming release
Former-commit-id: 13d5f3bd0dd844dbe2f709cfe8423a7417542744
This commit is contained in:
parent
e3876d793c
commit
df85be52a4
83
HISTORY.md
83
HISTORY.md
|
@ -28,6 +28,87 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
|
||||||
|
|
||||||
## Routing
|
## Routing
|
||||||
|
|
||||||
|
I wrote a [new router implementation](https://github.com/kataras/muxie#philosophy) for our Iris internal(low-level) routing mechanism, it is good to know that this was the second time we have updated the router internals without a single breaking change after the v6, thanks to the very well-writen and designed-first code we have for the high-level path syntax component called [macro interpreter](macro/interpreter).
|
||||||
|
|
||||||
|
The new router supports things like **closest wildcard resolution**.
|
||||||
|
|
||||||
|
> If the name doesn't sound good to you it is because I named that feature myself, I don't know any other framework or router that supports a thing like that so be gentle:)
|
||||||
|
|
||||||
|
Previously you couldn't register routes like: `/{myparam:path}` and `/static` and `/{myparam:string}` and `/{myparam:string}/static` and `/static/{myparam:string}` all in one path prefix without a "decision handler". And generally if you had a wildcard it was possible to add (a single) static part and (a single) named parameter but not without performance cost and limits, why only one? (one is better than nothing: look the Iris' alternatives) We struggle to overcome our own selves, now you **can definitely do it without a bit of performance cost**, and surely we hand't imagine the wildcard to **catch all if nothing else found** without huge routing performance cost, the wildcard(`:path`) meant ONLY: "accept one or more path segments and put them into the declared parameter" so if you had register a dynamic single-path-segment named parameter like `:string, :int, :uint, :alphabetical...` in between those path segments it wouldn't work. The **closest wildcard resolution** offers you the opportunity to design your APIs even better via custom handlers and error handlers like `404 not found` to path prefixes for your API's groups, now you can do it without any custom code for path resolution inside a "decision handler" or a middleware.
|
||||||
|
|
||||||
|
Code worths 1000 words, now it is possible to define your routes like this without any issues:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris"
|
||||||
|
"github.com/kataras/iris/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
// matches everyhing if nothing else found,
|
||||||
|
// so you can use it for custom 404 root-level/main pages!
|
||||||
|
app.Get("/{p:path}", func(ctx context.Context) {
|
||||||
|
path := ctx.Params().Get("p")
|
||||||
|
// gives the path without the first "/".
|
||||||
|
ctx.Writef("Site Custom 404 Error Message\nPage of: '%s' not found", path)
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Get("/", indexHandler)
|
||||||
|
|
||||||
|
// request: http://localhost:8080/profile
|
||||||
|
// response: "Profile Index"
|
||||||
|
app.Get("/profile", func(ctx context.Context) {
|
||||||
|
ctx.Writef("Profile Index")
|
||||||
|
})
|
||||||
|
|
||||||
|
// request: http://localhost:8080/profile/kataras
|
||||||
|
// response: "Profile of username: 'kataras'"
|
||||||
|
app.Get("/profile/{username}", func(ctx context.Context) {
|
||||||
|
username := ctx.Params().Get("username")
|
||||||
|
ctx.Writef("Profile of username: '%s'", username)
|
||||||
|
})
|
||||||
|
|
||||||
|
// request: http://localhost:8080/profile/settings
|
||||||
|
// response: "Profile personal settings"
|
||||||
|
app.Get("/profile/settings", func(ctx context.Context) {
|
||||||
|
ctx.Writef("Profile personal settings")
|
||||||
|
})
|
||||||
|
|
||||||
|
// request: http://localhost:8080/profile/settings/security
|
||||||
|
// response: "Profile personal security settings"
|
||||||
|
app.Get("/profile/settings/security", func(ctx context.Context) {
|
||||||
|
ctx.Writef("Profile personal security settings")
|
||||||
|
})
|
||||||
|
|
||||||
|
// matches everyhing /profile/*somethng_here*
|
||||||
|
// if no other route matches the path semgnet after the
|
||||||
|
// /profile or /profile/
|
||||||
|
//
|
||||||
|
// So, you can use it for custom 404 profile pages
|
||||||
|
// side-by-side to your root wildcard without issues!
|
||||||
|
// For example:
|
||||||
|
// request: http://localhost:8080/profile/kataras/what
|
||||||
|
// response:
|
||||||
|
// Profile Page Custom 404 Error Message
|
||||||
|
// Profile Page of: 'kataras/what' was unable to be found
|
||||||
|
app.Get("/profile/{p:path}", func(ctx context.Context) {
|
||||||
|
path := ctx.Params().Get("p")
|
||||||
|
ctx.Writef("Profile Page Custom 404 Error Message\nProfile Page of: '%s' not found", path)
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexHandler(ctx context.Context) {
|
||||||
|
ctx.HTML("This is the <strong>index page</strong>")
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
The `github.com/kataras/iris/core/router.AllMethods` is now a variable that can be altered by end-developers, so things like `app.Any` can register to custom methods as well, as requested at: https://github.com/kataras/iris/issues/1102. For example, import that package and do `router.AllMethods = append(router.AllMethods, "LINK")` in your `main` or `init` function.
|
The `github.com/kataras/iris/core/router.AllMethods` is now a variable that can be altered by end-developers, so things like `app.Any` can register to custom methods as well, as requested at: https://github.com/kataras/iris/issues/1102. For example, import that package and do `router.AllMethods = append(router.AllMethods, "LINK")` in your `main` or `init` function.
|
||||||
|
|
||||||
The old `github.com/kataras/iris/core/router/macro` package was moved to `guthub.com/kataras/iris/macro` to allow end-developers to add custom parameter types and macros, it supports all go standard types by default as you will see below.
|
The old `github.com/kataras/iris/core/router/macro` package was moved to `guthub.com/kataras/iris/macro` to allow end-developers to add custom parameter types and macros, it supports all go standard types by default as you will see below.
|
||||||
|
@ -48,7 +129,7 @@ Here is the full list of the built'n parameter types that we support now, includ
|
||||||
|
|
||||||
| Param Type | Go Type | Validation | Retrieve Helper |
|
| Param Type | Go Type | Validation | Retrieve Helper |
|
||||||
| -----------------|------|-------------|------|
|
| -----------------|------|-------------|------|
|
||||||
| `:string` | string | anything (single path segment) | `Params().Get` |
|
| `:string` | string | the default if param type is missing, anything (single path segment) | `Params().Get` |
|
||||||
| `:int` | int | -9223372036854775808 to 9223372036854775807 (x64) or -2147483648 to 2147483647 (x32), depends on the host arch | `Params().GetInt` |
|
| `:int` | int | -9223372036854775808 to 9223372036854775807 (x64) or -2147483648 to 2147483647 (x32), depends on the host arch | `Params().GetInt` |
|
||||||
| `:int8` | int8 | -128 to 127 | `Params().GetInt8` |
|
| `:int8` | int8 | -128 to 127 | `Params().GetInt8` |
|
||||||
| `:int16` | int16 | -32768 to 32767 | `Params().GetInt16` |
|
| `:int16` | int16 | -32768 to 32767 | `Params().GetInt16` |
|
||||||
|
|
|
@ -52,9 +52,9 @@ type (
|
||||||
func New(cfg Config) *Server {
|
func New(cfg Config) *Server {
|
||||||
cfg = cfg.Validate()
|
cfg = cfg.Validate()
|
||||||
return &Server{
|
return &Server{
|
||||||
config: cfg,
|
config: cfg,
|
||||||
connections: sync.Map{}, // ready-to-use, this is not necessary.
|
connections: sync.Map{}, // ready-to-use, this is not necessary.
|
||||||
rooms: make(map[string][]string),
|
rooms: make(map[string][]string),
|
||||||
onConnectionListeners: make([]ConnectionFunc, 0),
|
onConnectionListeners: make([]ConnectionFunc, 0),
|
||||||
upgrader: websocket.Upgrader{
|
upgrader: websocket.Upgrader{
|
||||||
HandshakeTimeout: cfg.HandshakeTimeout,
|
HandshakeTimeout: cfg.HandshakeTimeout,
|
||||||
|
@ -352,9 +352,12 @@ func (s *Server) GetConnectionsByRoom(roomName string) []Connection {
|
||||||
// let's keep it unexported for the best.
|
// let's keep it unexported for the best.
|
||||||
func (s *Server) emitMessage(from, to string, data []byte) {
|
func (s *Server) emitMessage(from, to string, data []byte) {
|
||||||
if to != All && to != Broadcast {
|
if to != All && to != Broadcast {
|
||||||
if s.rooms[to] != nil {
|
s.mu.RLock()
|
||||||
|
room := s.rooms[to]
|
||||||
|
s.mu.RUnlock()
|
||||||
|
if room != nil {
|
||||||
// it suppose to send the message to a specific room/or a user inside its own room
|
// it suppose to send the message to a specific room/or a user inside its own room
|
||||||
for _, connectionIDInsideRoom := range s.rooms[to] {
|
for _, connectionIDInsideRoom := range room {
|
||||||
if c, ok := s.getConnection(connectionIDInsideRoom); ok {
|
if c, ok := s.getConnection(connectionIDInsideRoom); ok {
|
||||||
c.writeDefault(data) //send the message to the client(s)
|
c.writeDefault(data) //send the message to the client(s)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user