versioning

package
v12.2.0-beta1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2022 License: BSD-3-Clause Imports: 6 Imported by: 8

Documentation

Index

Constants

View Source
const (
	APIWarnHeader            = "X-Api-Warn"
	APIDeprecationDateHeader = "X-Api-Deprecation-Date"
	APIDeprecationInfoHeader = "X-Api-Deprecation-Info"
)

The response header keys when a resource is deprecated by the server.

View Source
const (
	// APIVersionResponseHeader the response header which its value contains
	// the normalized semver matched version.
	APIVersionResponseHeader = "X-Api-Version"
	// AcceptVersionHeaderKey is the header key of "Accept-Version".
	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"
	// NotFound is the key that can be used inside a `Map` or inside `ctx.SetVersion(versioning.NotFound)`
	// to tell that a version wasn't found, therefore the `NotFoundHandler` should handle the request instead.
	NotFound = "iris.api.version.notfound"
	// Empty is just an empty string. Can be used as a key for a version alias
	// when the requested version of a resource was not even specified by the client.
	// The difference between NotFound and Empty is important when version aliases are registered:
	// - A NotFound cannot be registered as version alias, it
	//   means that the client sent a version with its request
	//   but that version was not implemented by the server.
	// - An Empty indicates that the client didn't send any version at all.
	Empty = ""
)

Variables

View Source
var DefaultDeprecationOptions = DeprecationOptions{
	WarnMessage: "WARNING! You are using a deprecated version of this API.",
}

DefaultDeprecationOptions are the default deprecation options, it defaults the "X-API-Warn" header to a generic message.

View Source
var ErrNotFound = fmt.Errorf("version %w", context.ErrNotFound)

ErrNotFound reports whether a requested version does not match with any of the server's implemented ones.

View Source
var NotFoundHandler = func(ctx *context.Context) {

	ctx.StopWithPlainError(501, ErrNotFound)
}

NotFoundHandler is the default version not found handler that is executed from `NewMatcher` when no version is registered as available to dispatch a resource.

Functions

func Aliases added in v12.2.0

func Aliases(aliases AliasMap) context.Handler

Aliases is a middleware which registers version constraint aliases for the children Parties(routers). It's respected by versioning Groups.

Example Code:

app := iris.New()

api := app.Party("/api")
api.Use(Aliases(map[string]string{
 versioning.Empty: "1.0.0", // when no version was provided by the client.
 "beta": "4.0.0",
 "stage": "5.0.0-alpha"
}))

v1 := NewGroup(api, ">=1.0.0 < 2.0.0")
v1.Get/Post...

v4 := NewGroup(api, ">=4.0.0 < 5.0.0")
v4.Get/Post...

stage := NewGroup(api, "5.0.0-alpha")
stage.Get/Post...

func Deprecated

func Deprecated(handler context.Handler, options DeprecationOptions) context.Handler

Deprecated wraps an existing API handler and marks it as a deprecated one. Deprecated can be used to tell the clients that a newer version of that specific resource is available instead.

func FromQuery added in v12.2.0

func FromQuery(urlQueryParameterName string, defaultVersion string) context.Handler

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 GetVersion

func GetVersion(ctx *context.Context) string

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.0" - "Accept-Version" header, i.e Accept-Version: "1.0.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).

See `SetVersion` too.

func GetVersionAlias added in v12.2.0

func GetVersionAlias(ctx *context.Context, gotVersion string) (string, bool)

GetVersionAlias returns the version alias of the given "gotVersion" or empty. It Reports whether the alias was found. See `SetVersionAliases`, `Aliases` and `Match` for more.

func Handler added in v12.2.0

func Handler(version string) context.Handler

Handler returns a handler which is only fired when the "version" is matched with the requested one. It is not meant to be used by end-developers (exported for version controller feature). Use `NewGroup` instead.

func If

func If(got string, expected string) bool

If reports whether the "got" matches the "expected" one. the "expected" can be a constraint like ">=1.0.0 <2.0.0". This function is just a helper, better use the Group instead.

func Match

func Match(ctx *context.Context, expectedVersion string) bool

Match reports whether the request matches the expected version. This function is just a helper, better use the Group instead.

func SetVersion added in v12.2.0

func SetVersion(ctx *context.Context, constraint string)

SetVersion force-sets the API Version. It can be used inside a middleware. 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
  version := ctx.URLParamDefault("version", "1.0.0")
  versioning.SetVersion(ctx, version)
	 ctx.Next()
 }

See `GetVersion` too.

func SetVersionAliases added in v12.2.0

func SetVersionAliases(ctx *context.Context, aliases AliasMap, override bool)

SetVersionAliases sets a map of version aliases when a requested version of a resource was not implemented by the server. Can be used inside a middleware to the parent Party and always before the child versioning groups (see `Aliases` function).

The map's key (string) should be the "got version" (by the client) and the value should be the "version constraint to match" instead. The map's value(string) should be a registered version otherwise it will hit the NotFoundHandler (501, "version not found" by default).

The given "aliases" is a type of standard map[string]string and should NOT be modified afterwards.

The last "override" input argument indicates whether any existing aliases, registered by previous handlers in the chain, should be overridden or copied to the previous map one.

func WriteDeprecated added in v12.2.0

func WriteDeprecated(ctx *context.Context, options DeprecationOptions)

WriteDeprecated writes the deprecated response headers based on the given "options". It can be used inside a middleware.

See `Deprecated` to wrap an existing handler instead.

Types

type API added in v12.2.0

type API = router.Party

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 AliasMap added in v12.2.0

type AliasMap = map[string]string

AliasMap is just a type alias of the standard map[string]string. Head over to the `Aliases` function below for more.

type DeprecationOptions

type DeprecationOptions struct {
	WarnMessage     string
	DeprecationDate time.Time
	DeprecationInfo string
}

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

func (DeprecationOptions) ShouldHandle

func (opts DeprecationOptions) ShouldHandle() bool

ShouldHandle reports whether the deprecation headers should be present or no.

type Group

type Group struct {
	API
	// contains filtered or unexported fields
}

Group represents a group of resources that should be handled based on a version requested by the client. See `NewGroup` for more.

func NewGroup

func NewGroup(r API, version string) *Group

NewGroup returns a version 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).

A version is extracted through the versioning.GetVersion function:

Accept-Version: 1.0.0
Accept: application/json; version=1.0.0

You can customize it by setting a version based on the request context:

 api.Use(func(ctx *context.Context) {
	 if version := ctx.URLParam("version"); version != "" {
	  SetVersion(ctx, version)
	 }

  ctx.Next()
 })

OR:

api.Use(versioning.FromQuery("version", ""))

Examples at: _examples/routing/versioning Usage:

app := iris.New()
api := app.Party("/api")
v1 := versioning.NewGroup(api, ">=1.0.0 <2.0.0")
v1.Get/Post/Put/Delete...

Valid ranges are:

  • "<1.0.0"
  • "<=1.0.0"
  • ">1.0.0"
  • ">=1.0.0"
  • "1.0.0", "=1.0.0", "==1.0.0"
  • "!1.0.0", "!=1.0.0"

A Range can consist of multiple ranges separated by space: Ranges can be linked by logical AND:

  • ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7"

but not "1.0.0" or "2.0.0"

  • ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0

except 2.0.3-beta.2

Ranges can also be linked by logical OR:

  • "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x"

AND has a higher precedence than OR. It's not possible to use brackets.

Ranges can be combined by both AND and OR

  • `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`,

but not `4.2.1`, `2.1.1`

func (*Group) Deprecated

func (g *Group) Deprecated(options DeprecationOptions) *Group

Deprecated marks this group and all its versioned routes as deprecated versions of that endpoint.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL