iris/versioning
Gerasimos (Makis) Maropoulos 70610af6fd add versioning/README.md
Former-commit-id: 7ea92fadc982038533675996704b6bf89e149aae
2018-11-11 02:18:19 +02:00
..
deprecation_test.go initialize support for versioning as requested, per route -- not finished yet 2018-11-10 03:49:32 +02:00
deprecation.go versioning API: initialize support for grouping 2018-11-10 23:29:24 +02:00
group.go versioning API: initialize support for grouping 2018-11-10 23:29:24 +02:00
README.md add versioning/README.md 2018-11-11 02:18:19 +02:00
version_test.go initialize support for versioning as requested, per route -- not finished yet 2018-11-10 03:49:32 +02:00
version.go versioning API: initialize support for grouping 2018-11-10 23:29:24 +02:00
versioning_test.go add versioning/README.md 2018-11-11 02:18:19 +02:00
versioning.go add versioning/README.md 2018-11-11 02:18:19 +02:00

Versioning

The versioning package provides semver versioning for your APIs. It implements all the suggestions written at api-guidelines and more.

The version comparison is done by the go-version package. It supports matching over patterns like ">= 1.0, < 3" and etc.

Features

  • per route version matching, a normal iris handler with "switch" cases via Map for version => handler
  • per group versioned routes and deprecation API
  • version matching like ">= 1.0, < 2.0" or just "2.0.1" and etc.
  • version not found handler (can be customized by simply adding the versioning.NotFound: customNotMatchVersionHandler on the Map)
  • version is retrieved from the "Accept" and "Accept-Version" headers (can be customized via middleware)
  • respond with "X-API-Version" header, if version found.
  • deprecation options with customizable "X-API-Warn", "X-API-Deprecation-Date", "X-API-Deprecation-Info" headers via Deprecated wrapper.

Get version

Current request version is retrieved by versioning.GetVersion(ctx).

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"

You can also set a custom version for a handler via a middleware by using the context's store values. For example:

func(ctx iris.Context) {
    ctx.Values().Set(versioning.Key, ctx.URLParamDefault("version", "1.0"))
    ctx.Next()
}

Match version to handler

The versioning.NewMatcher(versioning.Map) iris.Handler creates a single handler which decides what handler need to be executed based on the requested version.

app := iris.New()

// middleware for all versions.
myMiddleware := func(ctx iris.Context) {
    // [...]
    ctx.Next()
}

myCustomNotVersionFound := func(ctx iris.Context) {
    ctx.StatusCode(404)
    ctx.Writef("%s version not found", versioning.GetVersion(ctx))
}

userAPI := app.Party("/api/user")
userAPI.Get("/", myMiddleware, versioning.NewMatcher(versioning.Map{
    "1.0":               sendHandler(v10Response),
    ">= 2, < 3":         sendHandler(v2Response),
    versioning.NotFound: myCustomNotVersionFound,
}))

Grouping versioned routes

Impl & tests done, example not. TODO

Compare version manually from inside your handlers

// reports if the "version" is matching to the "is".
// the "is" can be a constraint like ">= 1, < 3".
If(version string, is string) bool
// same as `If` but expects a Context to read the requested version.
Match(ctx iris.Context, expectedVersion string) bool
app.Get("/api/user", func(ctx iris.Context) {
    if versioning.Match(ctx, ">= 2.2.3") {
        // [logic for >= 2.2.3 version of your handler goes here]
        return
    }
})