Skip to content
This repository has been archived by the owner on Dec 22, 2023. It is now read-only.

Commit

Permalink
Include supported API versions in error message
Browse files Browse the repository at this point in the history
  • Loading branch information
louischan-oursky committed Jan 14, 2020
1 parent 87031bf commit c776d48
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 22 deletions.
8 changes: 5 additions & 3 deletions pkg/core/apiversion/apiversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@ const MinorVersion = 1
// APIVersion is the current API Version.
var APIVersion = Format(MajorVersion, MinorVersion)

// SupportedVersions is a slice of supported versions.
var SupportedVersions []string

// SupportedVersionsJSON is an JSON array of supported versions.
var SupportedVersionsJSON string

var regexpAPIVersion = regexp.MustCompile(`^v(\d+)\.(\d+)$`)

func init() {
var supportedVersions []string
for i := 0; i <= MinorVersion; i++ {
supportedVersions = append(supportedVersions, Format(MajorVersion, i))
SupportedVersions = append(SupportedVersions, Format(MajorVersion, i))
}
bytes, err := json.Marshal(supportedVersions)
bytes, err := json.Marshal(SupportedVersions)
if err != nil {
panic(err)
}
Expand Down
32 changes: 17 additions & 15 deletions pkg/core/middleware/apiversion.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
package middleware

import (
"fmt"
"net/http"

"github.com/gorilla/mux"

"github.com/skygeario/skygear-server/pkg/core/apiversion"
"github.com/skygeario/skygear-server/pkg/core/handler"
"github.com/skygeario/skygear-server/pkg/core/skyerr"
)

var ErrIncompatibleAPIVersion = skyerr.NotFound.WithReason("IncompatibleAPIVersion").New("incompatible API version")
var IncompatibleAPIVersion = skyerr.NotFound.WithReason("IncompatibleAPIVersion")

// APIVersionMiddleware compares the API version with own version.
type APIVersionMiddleware struct {
// APIVersionName tells how to extract the API version from mux.Vars.
APIVersionName string
// MajorVersion determines the supported major version.
// It should be apiversion.MajorVersion in normal use case.
MajorVersion int
// MinorVersion determines the supported minor version.
// It should be apiversion.MinorVersion in normal use case.
MinorVersion int
// SupportedVersions determines the full list of supported versions.
SupportedVersions []string
// SupportedVersionsJSON is the JSON encoding of SupportedVersions.
SupportedVersionsJSON string
}

func (m *APIVersionMiddleware) Handle(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
apiVersion := mux.Vars(r)[m.APIVersionName]
major, minor, ok := apiversion.Parse(apiVersion)

if !ok || major != m.MajorVersion || minor > m.MinorVersion {
handler.WriteResponse(w, handler.APIResponse{
Error: ErrIncompatibleAPIVersion,
})
return
for _, supported := range m.SupportedVersions {
if apiVersion == supported {
next.ServeHTTP(w, r)
return
}
}
next.ServeHTTP(w, r)

handler.WriteResponse(w, handler.APIResponse{
Error: IncompatibleAPIVersion.New(
fmt.Sprintf("expected API versions: %s", m.SupportedVersionsJSON),
),
})
})
}
8 changes: 4 additions & 4 deletions pkg/core/middleware/apiversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ func TestAPIVersionMiddleware(t *testing.T) {
router := mux.NewRouter()
// own API version is v3.1
m := &APIVersionMiddleware{
APIVersionName: "api_version",
MajorVersion: 3,
MinorVersion: 1,
APIVersionName: "api_version",
SupportedVersions: []string{"v3.0", "v3.1"},
SupportedVersionsJSON: `["v3.0", "v3.1"]`,
}
router.Use(m.Handle)

Expand All @@ -44,7 +44,7 @@ func TestAPIVersionMiddleware(t *testing.T) {
{
"error": {
"code": 404,
"message": "incompatible API version",
"message": "expected API versions: [\"v3.0\", \"v3.1\"]",
"name": "NotFound",
"reason": "IncompatibleAPIVersion"
}
Expand Down

0 comments on commit c776d48

Please sign in to comment.