2018-11-10 22:29:24 +01:00
|
|
|
package versioning
|
|
|
|
|
|
|
|
import (
|
2019-10-25 00:27:02 +02:00
|
|
|
"github.com/kataras/iris/v12/context"
|
|
|
|
"github.com/kataras/iris/v12/core/router"
|
2018-11-10 22:29:24 +01:00
|
|
|
)
|
|
|
|
|
2021-01-06 00:52:39 +01:00
|
|
|
// Property to be defined inside the registered
|
|
|
|
// Party on NewGroup, useful for a party to know its (optional) version
|
|
|
|
// when the versioning feature is used.
|
|
|
|
const Property = "iris.party.version"
|
|
|
|
|
2021-01-05 17:16:32 +01:00
|
|
|
// API is a type alias of router.Party.
|
|
|
|
// This is required in order for a Group instance
|
|
|
|
// to implement the Party interface without field conflict.
|
|
|
|
type API = router.Party
|
|
|
|
|
2020-08-06 02:35:58 +02:00
|
|
|
// Group is a group of version-based routes.
|
|
|
|
// One version per one or more routes.
|
|
|
|
type Group struct {
|
2021-01-05 17:16:32 +01:00
|
|
|
API
|
2018-11-10 22:29:24 +01:00
|
|
|
|
2020-08-06 02:35:58 +02:00
|
|
|
// Information not currently in-use.
|
|
|
|
version string
|
|
|
|
deprecation DeprecationOptions
|
|
|
|
}
|
2018-11-10 22:29:24 +01:00
|
|
|
|
2021-01-06 00:52:39 +01:00
|
|
|
// NewGroup returns a ptr to Group based on the given "version" constraint.
|
|
|
|
// Group completes the Party interface.
|
|
|
|
// The returned Group wraps a cloned Party of the given "r" Party therefore,
|
|
|
|
// any changes to its parent won't affect this one (e.g. register global middlewares afterwards).
|
2020-11-06 13:19:53 +01:00
|
|
|
//
|
2021-01-06 00:52:39 +01:00
|
|
|
// Examples at: _examples/routing/versioning
|
2020-11-06 13:19:53 +01:00
|
|
|
// Usage:
|
2021-01-06 00:52:39 +01:00
|
|
|
// app := iris.New()
|
|
|
|
// api := app.Party("/api")
|
|
|
|
// v1 := versioning.NewGroup(api, ">= 1, < 2")
|
|
|
|
// v1.Get/Post/Put/Delete...
|
|
|
|
//
|
|
|
|
// See the `GetVersion` function to learn how
|
|
|
|
// a version is extracted and matched over this.
|
2020-08-06 02:35:58 +02:00
|
|
|
func NewGroup(r router.Party, version string) *Group {
|
2021-01-06 00:52:39 +01:00
|
|
|
r = r.Party("/")
|
|
|
|
r.Properties()[Property] = version
|
|
|
|
|
2020-08-06 02:35:58 +02:00
|
|
|
// Note that this feature alters the RouteRegisterRule to RouteOverlap
|
|
|
|
// the RouteOverlap rule does not contain any performance downside
|
|
|
|
// but it's good to know that if you registered other mode, this wanna change it.
|
|
|
|
r.SetRegisterRule(router.RouteOverlap)
|
|
|
|
r.UseOnce(Handler(version)) // this is required in order to not populate this middleware to the next group.
|
|
|
|
|
2018-11-10 22:29:24 +01:00
|
|
|
return &Group{
|
2021-01-05 17:16:32 +01:00
|
|
|
API: r,
|
2018-11-10 22:29:24 +01:00
|
|
|
version: version,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deprecated marks this group and all its versioned routes
|
|
|
|
// as deprecated versions of that endpoint.
|
|
|
|
func (g *Group) Deprecated(options DeprecationOptions) *Group {
|
2020-08-06 02:35:58 +02:00
|
|
|
// store it for future use, e.g. collect all deprecated APIs and notify the developer.
|
2018-11-10 22:29:24 +01:00
|
|
|
g.deprecation = options
|
|
|
|
|
2021-01-05 17:16:32 +01:00
|
|
|
g.API.UseOnce(func(ctx *context.Context) {
|
2020-08-06 02:35:58 +02:00
|
|
|
WriteDeprecated(ctx, options)
|
|
|
|
ctx.Next()
|
2018-11-11 16:27:31 +01:00
|
|
|
})
|
2020-08-06 02:35:58 +02:00
|
|
|
return g
|
2018-11-10 22:29:24 +01:00
|
|
|
}
|
2021-01-06 00:52:39 +01:00
|
|
|
|
|
|
|
// FromQuery is a simple helper which tries to
|
|
|
|
// set the version constraint from a given URL Query Parameter.
|
|
|
|
// The X-Api-Version is still valid.
|
|
|
|
func FromQuery(urlQueryParameterName string, defaultVersion string) context.Handler {
|
|
|
|
return func(ctx *context.Context) {
|
|
|
|
version := ctx.URLParam(urlQueryParameterName)
|
|
|
|
if version == "" {
|
|
|
|
version = defaultVersion
|
|
|
|
}
|
|
|
|
|
|
|
|
if version != "" {
|
|
|
|
SetVersion(ctx, version)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.Next()
|
|
|
|
}
|
|
|
|
}
|