Skip to content

Commit

Permalink
Merge pull request #2 from HUK-COBURG/dependency-update/kin-openapi-v…
Browse files Browse the repository at this point in the history
….052.0

updated kin-openapi to v0.52.0
  • Loading branch information
crissi98 authored Mar 23, 2021
2 parents dda7480 + 32b9f12 commit f8dc811
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 16 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[![Go](https://github.com/HUK-COBURG/openapirouter/actions/workflows/go.yml/badge.svg)](https://github.com/HUK-COBURG/openapirouter/actions/workflows/go.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/huk-coburg/openapirouter)](https://goreportcard.com/report/github.com/huk-coburg/openapirouter)
[![GoDoc](https://godoc.org/github.com/huk-coburg/openapirouter?status.svg)](https://godoc.org/github.com/huk-coburg/openapirouter)

# OpenAPI-Router
The OpenAPI-Router is a "Contract-First" http-Router, specifically designed for JSON-based REST-Services. It takes an
Expand Down Expand Up @@ -27,7 +28,7 @@ The router is created using the following `NewRouter` function with the path of
To enable the automatic response writing and error mapping, a custom handler function different from the standard
`http.HandlerFunc` is used for the implementation of endpoints. The following function signature is used:
```go
func(request *http.Request, pathParamerters map[string]string) (*Response, error)
func(request *http.Request, pathParamerters map[string]string) (*openapirouter.Response, error)
```
The parameters are:
- **request:** The pointer to the http.Request as in the standard `http.HandlerFunc`. It can be used to extract the
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/huk-coburg/openapirouter
go 1.15

require (
github.com/getkin/kin-openapi v0.50.0
github.com/getkin/kin-openapi v0.52.0
github.com/go-openapi/swag v0.19.14 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/stretchr/testify v1.7.0
Expand Down
35 changes: 21 additions & 14 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ import (
"errors"
"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/getkin/kin-openapi/routers"
"github.com/getkin/kin-openapi/routers/gorillamux"
"log"
"net/http"
"net/url"
"reflect"
)

// The Router which implements the described features. It implements http.Handler to be compatible with existing HTTP
// libraries.
type Router struct {
baseRouter *openapi3filter.Router
errMapper *errorMapper
baseRouter routers.Router
errMapper *errorMapper
implementations map[*routers.Route]requestHandler
}

// Creates a new Router with the path of a OpenAPI specification file in YAML or JSON format.
Expand All @@ -24,28 +26,33 @@ func NewRouter(swaggerPath string) (*Router, error) {
if err != nil {
return nil, err
}
router, err := gorillamux.NewRouter(swagger)
if err != nil {
return nil, err
}
return &Router{
baseRouter: openapi3filter.NewRouter().WithSwagger(swagger),
errMapper: &errorMapper{errorMapping: make(map[reflect.Type]*HTTPError)},
baseRouter: router,
errMapper: &errorMapper{errorMapping: make(map[reflect.Type]*HTTPError)},
implementations: make(map[*routers.Route]requestHandler),
}, nil
}

// Implementation of http.Handler that finds the requestHandler for an incoming request and validates the requests. It
// also adds the pathParameters to the requests Context so they can be extracted by the requestHandler
func (router *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
var response *Response
route, pathParams, err := router.baseRouter.FindRoute(request.Method, request.URL)
route, pathParams, err := router.baseRouter.FindRoute(request)
if err != nil {
if err.Error() == openapi3filter.ErrMethodNotAllowed.Error() {
if err.Error() == routers.ErrMethodNotAllowed.Error() {
response = NewHTTPError(http.StatusMethodNotAllowed, err.Error()).ToResponse()
} else {
response = NewHTTPError(http.StatusNotFound, err.Error()).ToResponse()
}
response.write(writer)
return
}
switch handler := route.Handler.(type) {
case *requestHandler:
handler, ok := router.implementations[route]
if ok {
err = openapi3filter.ValidateRequest(context.Background(), &openapi3filter.RequestValidationInput{
Request: request,
PathParams: pathParams,
Expand All @@ -64,25 +71,25 @@ func (router *Router) ServeHTTP(writer http.ResponseWriter, request *http.Reques
}
ctx := context.WithValue(request.Context(), pathParamsKey, pathParams)
handler.ServeHTTP(writer, request.WithContext(ctx))
default:
} else {
response = NewHTTPError(http.StatusNotImplemented).ToResponse()
response.write(writer)
return
}
}

// AddRequestHandler creates a new requestHandler for a specified method and path. It is used to set an implementation
// for an endpoint. The function panics, if the endpoint is not specified in the OpenAPI specification
func (router *Router) AddRequestHandler(method string, path string, handleFunc HandleRequestFunction) {
pathUrl, err := url.Parse(path)
request, err := http.NewRequest(method, path, nil)
if err != nil {
log.Panicln(err)
}
route, _, err := router.baseRouter.FindRoute(method, pathUrl)
route, _, err := router.baseRouter.FindRoute(request)
if err != nil {
log.Panicln(err)
}
route.Handler = &requestHandler{

router.implementations[route] = requestHandler{
errMapper: router.errMapper,
handlerFunction: handleFunc,
}
Expand Down

0 comments on commit f8dc811

Please sign in to comment.