mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
finalize the API
Former-commit-id: e680a9fc517c02eca66f83e42519c9820122fae8
This commit is contained in:
parent
6886fd98c8
commit
c74196c6d7
|
@ -90,7 +90,7 @@ This will make the handler to send these headers to the client:
|
||||||
Grouping routes by version is possible as well.
|
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.
|
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`.
|
The `versioning.RegisterGroups(r iris.Party, versionNotFoundHandler iris.Handler, groups ...*versioning.Group)` must be called in the end in order to register the routes to a specific `Party`.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
@ -106,9 +106,11 @@ userAPIV2.Get("/", sendHandler(v2Response))
|
||||||
userAPIV2.Post("/", sendHandler(v2Response))
|
userAPIV2.Post("/", sendHandler(v2Response))
|
||||||
userAPIV2.Put("/other", sendHandler(v2Response))
|
userAPIV2.Put("/other", sendHandler(v2Response))
|
||||||
|
|
||||||
versioning.RegisterGroups(userAPI, userAPIV10, userAPIV2)
|
versioning.RegisterGroups(userAPI, versioning.NotFoundHandler, userAPIV10, userAPIV2)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> A middleware can be registered to the actual `iris.Party` only, using the methods we learnt above, i.e by using the `versioning.Match` in order to detect what code/handler you want to be executed when "x" or no version is requested.
|
||||||
|
|
||||||
### Deprecation for Group
|
### 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.
|
Just call the `Deprecated(versioning.DeprecationOptions)` on the group you want to notify your API consumers that this specific version is deprecated.
|
||||||
|
@ -117,17 +119,6 @@ Just call the `Deprecated(versioning.DeprecationOptions)` on the group you want
|
||||||
userAPIV10 := versioning.NewGroup("1.0").Deprecated(versioning.DefaultDeprecationOptions)
|
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
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
|
@ -6,20 +6,30 @@ import (
|
||||||
"github.com/kataras/iris/context"
|
"github.com/kataras/iris/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeprecationOptions describes the deprecation headers key-values.
|
||||||
|
// - "X-API-Warn": options.WarnMessage
|
||||||
|
// - "X-API-Deprecation-Date": context.FormatTime(ctx, options.DeprecationDate))
|
||||||
|
// - "X-API-Deprecation-Info": options.DeprecationInfo
|
||||||
type DeprecationOptions struct {
|
type DeprecationOptions struct {
|
||||||
WarnMessage string
|
WarnMessage string
|
||||||
DeprecationDate time.Time
|
DeprecationDate time.Time
|
||||||
DeprecationInfo string
|
DeprecationInfo string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShouldHandle reports whether the deprecation headers should be present or no.
|
||||||
func (opts DeprecationOptions) ShouldHandle() bool {
|
func (opts DeprecationOptions) ShouldHandle() bool {
|
||||||
return opts.WarnMessage != "" || !opts.DeprecationDate.IsZero() || opts.DeprecationInfo != ""
|
return opts.WarnMessage != "" || !opts.DeprecationDate.IsZero() || opts.DeprecationInfo != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultDeprecationOptions are the default deprecation options,
|
||||||
|
// it defaults the "X-API-Warn" header to a generic message.
|
||||||
var DefaultDeprecationOptions = DeprecationOptions{
|
var DefaultDeprecationOptions = DeprecationOptions{
|
||||||
WarnMessage: "WARNING! You are using a deprecated version of this API.",
|
WarnMessage: "WARNING! You are using a deprecated version of this API.",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated marks a specific handler as a deprecated.
|
||||||
|
// Deprecated can be used to tell the clients that
|
||||||
|
// a newer version of that specific resource is available instead.
|
||||||
func Deprecated(handler context.Handler, options DeprecationOptions) context.Handler {
|
func Deprecated(handler context.Handler, options DeprecationOptions) context.Handler {
|
||||||
if options.WarnMessage == "" {
|
if options.WarnMessage == "" {
|
||||||
options.WarnMessage = DefaultDeprecationOptions.WarnMessage
|
options.WarnMessage = DefaultDeprecationOptions.WarnMessage
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package versioning
|
package versioning
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/kataras/iris/context"
|
"github.com/kataras/iris/context"
|
||||||
"github.com/kataras/iris/core/router"
|
"github.com/kataras/iris/core/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterGroups(r router.Party, groups ...*Group) []*router.Route {
|
|
||||||
return Concat(groups...).For(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
vroute struct {
|
vroute struct {
|
||||||
method string
|
method string
|
||||||
|
@ -16,6 +14,8 @@ type (
|
||||||
versions Map
|
versions Map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Group is a group of version-based routes.
|
||||||
|
// One version per one or more routes.
|
||||||
Group struct {
|
Group struct {
|
||||||
version string
|
version string
|
||||||
extraMethods []string
|
extraMethods []string
|
||||||
|
@ -25,6 +25,9 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewGroup returns a ptr to Group based on the given "version".
|
||||||
|
//
|
||||||
|
// See `Handle` and `RegisterGroups` for more.
|
||||||
func NewGroup(version string) *Group {
|
func NewGroup(version string) *Group {
|
||||||
return &Group{
|
return &Group{
|
||||||
version: version,
|
version: version,
|
||||||
|
@ -33,7 +36,7 @@ func NewGroup(version string) *Group {
|
||||||
|
|
||||||
// Deprecated marks this group and all its versioned routes
|
// Deprecated marks this group and all its versioned routes
|
||||||
// as deprecated versions of that endpoint.
|
// as deprecated versions of that endpoint.
|
||||||
// It can be called in the end just before `Concat` or `RegisterGroups`
|
// It can be called in the end just before `RegisterGroups`
|
||||||
// or first by `NewGroup(...).Deprecated(...)`. It returns itself.
|
// or first by `NewGroup(...).Deprecated(...)`. It returns itself.
|
||||||
func (g *Group) Deprecated(options DeprecationOptions) *Group {
|
func (g *Group) Deprecated(options DeprecationOptions) *Group {
|
||||||
// if `Deprecated` is called in the end.
|
// if `Deprecated` is called in the end.
|
||||||
|
@ -47,13 +50,16 @@ func (g *Group) Deprecated(options DeprecationOptions) *Group {
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllowMethods can be called before `Handle/Get/Post...`
|
||||||
|
// to tell the underline router that all routes should be registered
|
||||||
|
// to these "methods" as well.
|
||||||
func (g *Group) AllowMethods(methods ...string) *Group {
|
func (g *Group) AllowMethods(methods ...string) *Group {
|
||||||
g.extraMethods = append(g.extraMethods, methods...)
|
g.extraMethods = append(g.extraMethods, methods...)
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Group) addVRoute(method, path string, handler context.Handler) {
|
func (g *Group) addVRoute(method, path string, handler context.Handler) {
|
||||||
for _, r := range g.routes { // check if already exists.
|
for _, r := range g.routes { // check if route already exists.
|
||||||
if r.method == method && r.path == path {
|
if r.method == method && r.path == path {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -67,8 +73,10 @@ func (g *Group) addVRoute(method, path string, handler context.Handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle registers a versioned route to the group.
|
// Handle registers a versioned route to the group.
|
||||||
|
// A call of `RegisterGroups` is necessary in order to register the actual routes
|
||||||
|
// when the group is complete.
|
||||||
//
|
//
|
||||||
// See `Concat` and `RegisterGroups` for more.
|
// `RegisterGroups` for more.
|
||||||
func (g *Group) Handle(method string, path string, handler context.Handler) {
|
func (g *Group) Handle(method string, path string, handler context.Handler) {
|
||||||
if g.deprecation.ShouldHandle() { // if `Deprecated` called first.
|
if g.deprecation.ShouldHandle() { // if `Deprecated` called first.
|
||||||
handler = Deprecated(handler, g.deprecation)
|
handler = Deprecated(handler, g.deprecation)
|
||||||
|
@ -89,47 +97,47 @@ func (g *Group) None(path string, handler context.Handler) {
|
||||||
|
|
||||||
// Get registers a versioned route for the Get http method.
|
// Get registers a versioned route for the Get http method.
|
||||||
func (g *Group) Get(path string, handler context.Handler) {
|
func (g *Group) Get(path string, handler context.Handler) {
|
||||||
g.Handle("GET", path, handler)
|
g.Handle(http.MethodGet, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post registers a versioned route for the Post http method.
|
// Post registers a versioned route for the Post http method.
|
||||||
func (g *Group) Post(path string, handler context.Handler) {
|
func (g *Group) Post(path string, handler context.Handler) {
|
||||||
g.Handle("POST", path, handler)
|
g.Handle(http.MethodPost, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put registers a versioned route for the Put http method
|
// Put registers a versioned route for the Put http method
|
||||||
func (g *Group) Put(path string, handler context.Handler) {
|
func (g *Group) Put(path string, handler context.Handler) {
|
||||||
g.Handle("PUT", path, handler)
|
g.Handle(http.MethodPut, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete registers a versioned route for the Delete http method.
|
// Delete registers a versioned route for the Delete http method.
|
||||||
func (g *Group) Delete(path string, handler context.Handler) {
|
func (g *Group) Delete(path string, handler context.Handler) {
|
||||||
g.Handle("DELETE", path, handler)
|
g.Handle(http.MethodDelete, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect registers a versioned route for the Connect http method.
|
// Connect registers a versioned route for the Connect http method.
|
||||||
func (g *Group) Connect(path string, handler context.Handler) {
|
func (g *Group) Connect(path string, handler context.Handler) {
|
||||||
g.Handle("CONNECT", path, handler)
|
g.Handle(http.MethodConnect, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head registers a versioned route for the Head http method.
|
// Head registers a versioned route for the Head http method.
|
||||||
func (g *Group) Head(path string, handler context.Handler) {
|
func (g *Group) Head(path string, handler context.Handler) {
|
||||||
g.Handle("HEAD", path, handler)
|
g.Handle(http.MethodHead, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options registers a versioned route for the Options http method.
|
// Options registers a versioned route for the Options http method.
|
||||||
func (g *Group) Options(path string, handler context.Handler) {
|
func (g *Group) Options(path string, handler context.Handler) {
|
||||||
g.Handle("OPTIONS", path, handler)
|
g.Handle(http.MethodOptions, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch registers a versioned route for the Patch http method.
|
// Patch registers a versioned route for the Patch http method.
|
||||||
func (g *Group) Patch(path string, handler context.Handler) {
|
func (g *Group) Patch(path string, handler context.Handler) {
|
||||||
g.Handle("PATCH", path, handler)
|
g.Handle(http.MethodPatch, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace registers a versioned route for the Trace http method.
|
// Trace registers a versioned route for the Trace http method.
|
||||||
func (g *Group) Trace(path string, handler context.Handler) {
|
func (g *Group) Trace(path string, handler context.Handler) {
|
||||||
g.Handle("TRACE", path, handler)
|
g.Handle(http.MethodTrace, path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any registers a versioned route for ALL of the http methods
|
// Any registers a versioned route for ALL of the http methods
|
||||||
|
@ -146,49 +154,31 @@ func (g *Group) Any(registeredPath string, handler context.Handler) {
|
||||||
g.Trace(registeredPath, handler)
|
g.Trace(registeredPath, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Groups struct {
|
// RegisterGroups registers one or more groups to an `iris.Party` or to the root router.
|
||||||
routes []vroute
|
// See `NewGroup` and `NotFoundHandler` too.
|
||||||
|
func RegisterGroups(r router.Party, notFoundHandler context.Handler, groups ...*Group) (actualRoutes []*router.Route) {
|
||||||
notFoundHandler context.Handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func Concat(groups ...*Group) *Groups {
|
|
||||||
var total []vroute
|
var total []vroute
|
||||||
|
|
||||||
for _, g := range groups {
|
for _, g := range groups {
|
||||||
inner:
|
inner:
|
||||||
for _, r := range g.routes {
|
for _, r := range g.routes {
|
||||||
for i, tr := range total {
|
for i, tr := range total {
|
||||||
if tr.method == r.method && tr.path == r.path {
|
if tr.method == r.method && tr.path == r.path {
|
||||||
for k, v := range r.versions {
|
total[i].versions[g.version] = r.versions[g.version]
|
||||||
total[i].versions[k] = v
|
|
||||||
}
|
|
||||||
continue inner
|
continue inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
total = append(total, g.routes...)
|
total = append(total, r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Groups{total, NotFoundHandler}
|
for _, vr := range total {
|
||||||
}
|
if notFoundHandler != nil {
|
||||||
|
vr.versions[NotFound] = notFoundHandler
|
||||||
func (g *Groups) NotFound(handler context.Handler) *Groups {
|
|
||||||
g.notFoundHandler = handler
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Groups) For(r router.Party) (totalRoutesRegistered []*router.Route) {
|
|
||||||
for _, vr := range g.routes {
|
|
||||||
if g.notFoundHandler != nil {
|
|
||||||
vr.versions[NotFound] = g.notFoundHandler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmt.Printf("Method: %s | Path: %s | Versions: %#+v\n", vr.method, vr.path, vr.versions)
|
route := r.Handle(vr.method, vr.path, NewMatcher(vr.versions))
|
||||||
route := r.Handle(vr.method, vr.path,
|
actualRoutes = append(actualRoutes, route)
|
||||||
NewMatcher(vr.versions))
|
|
||||||
totalRoutesRegistered = append(totalRoutesRegistered, route)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -7,14 +7,28 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AcceptVersionHeaderKey = "Accept-Version"
|
// AcceptVersionHeaderKey is the header key of "Accept-Version".
|
||||||
AcceptHeaderKey = "Accept"
|
AcceptVersionHeaderKey = "Accept-Version"
|
||||||
|
// AcceptHeaderKey is the header key of "Accept".
|
||||||
|
AcceptHeaderKey = "Accept"
|
||||||
|
// AcceptHeaderVersionValue is the Accept's header value search term the requested version.
|
||||||
AcceptHeaderVersionValue = "version"
|
AcceptHeaderVersionValue = "version"
|
||||||
|
|
||||||
Key = "iris.api.version" // for use inside the ctx.Values(), not visible by the user.
|
// Key is the context key of the version, can be used to manually modify the "requested" version.
|
||||||
|
// Example of how you can change the default behavior to extract a requested version (which is by headers)
|
||||||
|
// from a "version" url parameter instead:
|
||||||
|
// func(ctx iris.Context) { // &version=1
|
||||||
|
// ctx.Values().Set(versioning.Key, ctx.URLParamDefault("version", "1"))
|
||||||
|
// ctx.Next()
|
||||||
|
// }
|
||||||
|
Key = "iris.api.version" // for use inside the ctx.Values(), not visible by the user.
|
||||||
|
// NotFound is the key that can be used inside a `Map` or inside `ctx.Values().Set(versioning.Key, versioning.NotFound)`
|
||||||
|
// to tell that a version wasn't found, therefore the not found handler should handle the request instead.
|
||||||
NotFound = Key + ".notfound"
|
NotFound = Key + ".notfound"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NotFoundHandler is the default version not found handler that
|
||||||
|
// is executed from `NewMatcher` when no version is registered as available to dispatch a resource.
|
||||||
var NotFoundHandler = func(ctx context.Context) {
|
var NotFoundHandler = func(ctx context.Context) {
|
||||||
// 303 is an option too,
|
// 303 is an option too,
|
||||||
// end-dev has the chance to change that behavior by using the NotFound in the map:
|
// end-dev has the chance to change that behavior by using the NotFound in the map:
|
||||||
|
@ -32,6 +46,14 @@ var NotFoundHandler = func(ctx context.Context) {
|
||||||
ctx.WriteString("version not found")
|
ctx.WriteString("version not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetVersion returns the current request version.
|
||||||
|
//
|
||||||
|
// By default the `GetVersion` will try to read from:
|
||||||
|
// - "Accept" header, i.e Accept: "application/json; version=1.0"
|
||||||
|
// - "Accept-Version" header, i.e Accept-Version: "1.0"
|
||||||
|
//
|
||||||
|
// However, the end developer can also set a custom version for a handler via a middleware by using the context's store key
|
||||||
|
// for versions (see `Key` for further details on that).
|
||||||
func GetVersion(ctx context.Context) string {
|
func GetVersion(ctx context.Context) string {
|
||||||
// firstly by context store, if manually set-ed by a middleware.
|
// firstly by context store, if manually set-ed by a middleware.
|
||||||
if version := ctx.Values().GetString(Key); version != "" {
|
if version := ctx.Values().GetString(Key); version != "" {
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// If reports whether the "version" is matching to the "is".
|
||||||
|
// the "is" can be a constraint like ">= 1, < 3".
|
||||||
func If(v string, is string) bool {
|
func If(v string, is string) bool {
|
||||||
ver, err := version.NewVersion(v)
|
ver, err := version.NewVersion(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -20,12 +22,22 @@ func If(v string, is string) bool {
|
||||||
return constraints.Check(ver)
|
return constraints.Check(ver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Match acts exactly the same as `If` does but instead it accepts
|
||||||
|
// a Context, so it can be called by a handler to determinate the requested version.
|
||||||
func Match(ctx context.Context, expectedVersion string) bool {
|
func Match(ctx context.Context, expectedVersion string) bool {
|
||||||
return If(GetVersion(ctx), expectedVersion)
|
return If(GetVersion(ctx), expectedVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map is a map of versions targets to a handlers,
|
||||||
|
// a handler per version or constraint, the key can be something like ">1, <=2" or just "1".
|
||||||
type Map map[string]context.Handler
|
type Map map[string]context.Handler
|
||||||
|
|
||||||
|
// NewMatcher creates a single handler which decides what handler
|
||||||
|
// should be executed based on the requested version.
|
||||||
|
//
|
||||||
|
// Use the `NewGroup` if you want to add many routes under a specific version.
|
||||||
|
//
|
||||||
|
// See `Map` and `NewGroup` too.
|
||||||
func NewMatcher(versions Map) context.Handler {
|
func NewMatcher(versions Map) context.Handler {
|
||||||
constraintsHandlers, notFoundHandler := buildConstraints(versions)
|
constraintsHandlers, notFoundHandler := buildConstraints(versions)
|
||||||
|
|
||||||
|
|
|
@ -79,25 +79,40 @@ func TestNewGroup(t *testing.T) {
|
||||||
// [... static serving, middlewares and etc goes here].
|
// [... static serving, middlewares and etc goes here].
|
||||||
|
|
||||||
userAPIV10 := versioning.NewGroup("1.0").Deprecated(versioning.DefaultDeprecationOptions)
|
userAPIV10 := versioning.NewGroup("1.0").Deprecated(versioning.DefaultDeprecationOptions)
|
||||||
userAPIV10.Get("/", sendHandler(v10Response))
|
// V10middlewareResponse := "m1"
|
||||||
|
// userAPIV10.Use(func(ctx iris.Context) {
|
||||||
|
// println("exec userAPIV10.Use - midl1")
|
||||||
|
// sendHandler(V10middlewareResponse)(ctx)
|
||||||
|
// ctx.Next()
|
||||||
|
// })
|
||||||
|
// userAPIV10.Use(func(ctx iris.Context) {
|
||||||
|
// println("exec userAPIV10.Use - midl2")
|
||||||
|
// sendHandler(V10middlewareResponse + "midl2")(ctx)
|
||||||
|
// ctx.Next()
|
||||||
|
// })
|
||||||
|
// userAPIV10.Use(func(ctx iris.Context) {
|
||||||
|
// println("exec userAPIV10.Use - midl3")
|
||||||
|
// ctx.Next()
|
||||||
|
// })
|
||||||
|
|
||||||
|
userAPIV10.Get("/", sendHandler(v10Response))
|
||||||
userAPIV2 := versioning.NewGroup(">= 2, < 3")
|
userAPIV2 := versioning.NewGroup(">= 2, < 3")
|
||||||
|
// V2middlewareResponse := "m2"
|
||||||
|
// userAPIV2.Use(func(ctx iris.Context) {
|
||||||
|
// println("exec userAPIV2.Use - midl1")
|
||||||
|
// sendHandler(V2middlewareResponse)(ctx)
|
||||||
|
// ctx.Next()
|
||||||
|
// })
|
||||||
|
// userAPIV2.Use(func(ctx iris.Context) {
|
||||||
|
// println("exec userAPIV2.Use - midl2")
|
||||||
|
// ctx.Next()
|
||||||
|
// })
|
||||||
|
|
||||||
userAPIV2.Get("/", sendHandler(v2Response))
|
userAPIV2.Get("/", sendHandler(v2Response))
|
||||||
userAPIV2.Post("/", sendHandler(v2Response))
|
userAPIV2.Post("/", sendHandler(v2Response))
|
||||||
userAPIV2.Put("/other", sendHandler(v2Response))
|
userAPIV2.Put("/other", sendHandler(v2Response))
|
||||||
|
|
||||||
// versioning.Concat(userAPIV10, userAPIV2).
|
versioning.RegisterGroups(userAPI, versioning.NotFoundHandler, userAPIV10, userAPIV2)
|
||||||
// NotFound(func(ctx iris.Context) {
|
|
||||||
// ctx.StatusCode(iris.StatusNotFound)
|
|
||||||
// ctx.Writef("unknown version %s", versioning.GetVersion(ctx))
|
|
||||||
// }).
|
|
||||||
// For(userAPI)
|
|
||||||
// This is legal too:
|
|
||||||
// For(app.PartyFunc("/api/user", func(r iris.Party) {
|
|
||||||
// // [... static serving, middlewares and etc goes here].
|
|
||||||
// }))
|
|
||||||
|
|
||||||
versioning.RegisterGroups(userAPI, userAPIV10, userAPIV2)
|
|
||||||
|
|
||||||
e := httptest.New(t, app)
|
e := httptest.New(t, app)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user