mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
complete the versioning/README.md and add AllowMethods
like the normal Party, version-specific middlewares are not needed because the end-developer should declare a middleware with manual matching of version using versioning.Match(ctx, version) bool instead
Former-commit-id: 4f4c23dd7c043d5ab735070ae4d59ea84e3af2e0
This commit is contained in:
parent
70610af6fd
commit
6886fd98c8
|
@ -58,9 +58,75 @@ userAPI.Get("/", myMiddleware, versioning.NewMatcher(versioning.Map{
|
||||||
}))
|
}))
|
||||||
```
|
```
|
||||||
|
|
||||||
## Grouping versioned routes
|
### Deprecation
|
||||||
|
|
||||||
Impl & tests done, example not. **TODO**
|
Using the `versioning.Deprecated(handler iris.Handler, options versioning.DeprecationOptions) iris.Handler` function you can mark a specific handler version as deprecated.
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
v10Handler := versioning.Deprecated(sendHandler(v10Response), versioning.DeprecationOptions{
|
||||||
|
// if empty defaults to: "WARNING! You are using a deprecated version of this API."
|
||||||
|
WarnMessage string
|
||||||
|
DeprecationDate time.Time
|
||||||
|
DeprecationInfo string
|
||||||
|
})
|
||||||
|
|
||||||
|
userAPI.Get("/", versioning.NewMatcher(versioning.Map{
|
||||||
|
"1.0": v10Handler,
|
||||||
|
// [...]
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
This will make the handler to send these headers to the client:
|
||||||
|
|
||||||
|
- `"X-API-Warn": options.WarnMessage`
|
||||||
|
- `"X-API-Deprecation-Date": context.FormatTime(ctx, options.DeprecationDate))`
|
||||||
|
- `"X-API-Deprecation-Info": options.DeprecationInfo`
|
||||||
|
|
||||||
|
> versioning.DefaultDeprecationOptions can be passed instead if you don't care about Date and Info.
|
||||||
|
|
||||||
|
## Grouping routes by version
|
||||||
|
|
||||||
|
Grouping routes by version is possible as well.
|
||||||
|
|
||||||
|
Using the `versioning.NewGroup(version string) *versioning.Group` function you can create a group to register your versioned routes.
|
||||||
|
The `versioning.RegisterGroups(r iris.Party, groups ...*versioning.Group)` must be called in the end in order to register the routes to a specific `Party`.
|
||||||
|
|
||||||
|
```go
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
userAPI := app.Party("/api/user")
|
||||||
|
// [... static serving, middlewares and etc goes here].
|
||||||
|
|
||||||
|
userAPIV10 := versioning.NewGroup("1.0")
|
||||||
|
userAPIV10.Get("/", sendHandler(v10Response))
|
||||||
|
|
||||||
|
userAPIV2 := versioning.NewGroup(">= 2, < 3")
|
||||||
|
userAPIV2.Get("/", sendHandler(v2Response))
|
||||||
|
userAPIV2.Post("/", sendHandler(v2Response))
|
||||||
|
userAPIV2.Put("/other", sendHandler(v2Response))
|
||||||
|
|
||||||
|
versioning.RegisterGroups(userAPI, userAPIV10, userAPIV2)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deprecation for Group
|
||||||
|
|
||||||
|
Just call the `Deprecated(versioning.DeprecationOptions)` on the group you want to notify your API consumers that this specific version is deprecated.
|
||||||
|
|
||||||
|
```go
|
||||||
|
userAPIV10 := versioning.NewGroup("1.0").Deprecated(versioning.DefaultDeprecationOptions)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Version not found for Groups
|
||||||
|
|
||||||
|
In order to register a custom version not found handler you have to use the `versioning.Concat` first, which gives you the API to add a version not found handler.
|
||||||
|
|
||||||
|
```go
|
||||||
|
versioning.Concat(userAPIV10, userAPIV2).NotFound(func(ctx iris.Context) {
|
||||||
|
ctx.StatusCode(iris.StatusNotFound)
|
||||||
|
ctx.Writef("unknown version %s", versioning.GetVersion(ctx))
|
||||||
|
}).For(userAPI)
|
||||||
|
```
|
||||||
|
|
||||||
## Compare version manually from inside your handlers
|
## Compare version manually from inside your handlers
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ type (
|
||||||
|
|
||||||
Group struct {
|
Group struct {
|
||||||
version string
|
version string
|
||||||
|
extraMethods []string
|
||||||
routes []vroute
|
routes []vroute
|
||||||
|
|
||||||
deprecation DeprecationOptions
|
deprecation DeprecationOptions
|
||||||
|
@ -46,21 +47,40 @@ func (g *Group) Deprecated(options DeprecationOptions) *Group {
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle registers a versioned route to the group.
|
func (g *Group) AllowMethods(methods ...string) *Group {
|
||||||
//
|
g.extraMethods = append(g.extraMethods, methods...)
|
||||||
// See `Concat` and `RegisterGroups` for more.
|
return g
|
||||||
func (g *Group) Handle(method string, registeredPath string, handler context.Handler) {
|
}
|
||||||
if g.deprecation.ShouldHandle() { // if `Deprecated` called first.
|
|
||||||
handler = Deprecated(handler, g.deprecation)
|
func (g *Group) addVRoute(method, path string, handler context.Handler) {
|
||||||
|
for _, r := range g.routes { // check if already exists.
|
||||||
|
if r.method == method && r.path == path {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g.routes = append(g.routes, vroute{
|
g.routes = append(g.routes, vroute{
|
||||||
method: method,
|
method: method,
|
||||||
path: registeredPath,
|
path: path,
|
||||||
versions: Map{g.version: handler},
|
versions: Map{g.version: handler},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle registers a versioned route to the group.
|
||||||
|
//
|
||||||
|
// See `Concat` and `RegisterGroups` for more.
|
||||||
|
func (g *Group) Handle(method string, path string, handler context.Handler) {
|
||||||
|
if g.deprecation.ShouldHandle() { // if `Deprecated` called first.
|
||||||
|
handler = Deprecated(handler, g.deprecation)
|
||||||
|
}
|
||||||
|
|
||||||
|
methods := append(g.extraMethods, method)
|
||||||
|
|
||||||
|
for _, method := range methods {
|
||||||
|
g.addVRoute(method, path, handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// None registers an "offline" versioned route
|
// None registers an "offline" versioned route
|
||||||
// see `context#ExecRoute(routeName)` and routing examples.
|
// see `context#ExecRoute(routeName)` and routing examples.
|
||||||
func (g *Group) None(path string, handler context.Handler) {
|
func (g *Group) None(path string, handler context.Handler) {
|
||||||
|
|
|
@ -86,7 +86,7 @@ func TestNewGroup(t *testing.T) {
|
||||||
userAPIV2.Post("/", sendHandler(v2Response))
|
userAPIV2.Post("/", sendHandler(v2Response))
|
||||||
userAPIV2.Put("/other", sendHandler(v2Response))
|
userAPIV2.Put("/other", sendHandler(v2Response))
|
||||||
|
|
||||||
// versioning.Concat(userAPIV10, userAPIV2)
|
// versioning.Concat(userAPIV10, userAPIV2).
|
||||||
// NotFound(func(ctx iris.Context) {
|
// NotFound(func(ctx iris.Context) {
|
||||||
// ctx.StatusCode(iris.StatusNotFound)
|
// ctx.StatusCode(iris.StatusNotFound)
|
||||||
// ctx.Writef("unknown version %s", versioning.GetVersion(ctx))
|
// ctx.Writef("unknown version %s", versioning.GetVersion(ctx))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user