Documentation ¶
Overview ¶
Package gorillamux provides OpenAPI docs collector for gorilla/mux web services.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func PathToURLValues ¶
PathToURLValues is a decoder function for parameters in path.
Example ¶
package main import ( "bytes" "fmt" "net/http" "net/http/httptest" "github.com/gorilla/mux" "github.com/swaggest/rest" "github.com/swaggest/rest/gorillamux" "github.com/swaggest/rest/request" ) func main() { // Instantiate decoder factory with gorillamux.PathToURLValues. // Single factory can be used to create multiple request decoders. decoderFactory := request.NewDecoderFactory() decoderFactory.ApplyDefaults = true decoderFactory.SetDecoderFunc(rest.ParamInPath, gorillamux.PathToURLValues) // Define request structure for your HTTP handler. type myRequest struct { Query1 int `query:"query1"` Path1 string `path:"path1"` Path2 int `path:"path2"` Header1 float64 `header:"X-Header-1"` FormData1 bool `formData:"formData1"` FormData2 string `formData:"formData2"` } // Create decoder for that request structure. dec := decoderFactory.MakeDecoder(http.MethodPost, myRequest{}, nil) router := mux.NewRouter() // Now in router handler you can decode *http.Request into a Go structure. router.Handle("/foo/{path1}/bar/{path2}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var in myRequest _ = dec.Decode(r, &in, nil) fmt.Printf("%+v\n", in) })) // Serving example URL. w := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodPost, "/foo/abc/bar/123?query1=321", bytes.NewBufferString("formData1=true&formData2=def")) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("X-Header-1", "1.23") router.ServeHTTP(w, req) }
Output: {Query1:321 Path1:abc Path2:123 Header1:1.23 FormData1:true FormData2:def}
Types ¶
type OpenAPICollector ¶
type OpenAPICollector struct { // Collector is an actual OpenAPI collector. Collector *openapi.Collector // DefaultMethods list is used when handler serves all methods. DefaultMethods []string // OperationExtractor allows flexible extraction of OpenAPI information. OperationExtractor func(h http.Handler) func(oc oapi.OperationContext) error // Host filters routes by host, gorilla/mux can serve different handlers at // same method, paths with different hosts. This can not be expressed with a single // OpenAPI document. Host string }
OpenAPICollector is a wrapper for openapi.Collector tailored to walk gorilla/mux router.
func NewOpenAPICollector ¶
func NewOpenAPICollector(r oapi.Reflector) *OpenAPICollector
NewOpenAPICollector creates route walker for gorilla/mux, that collects OpenAPI operations.
Example ¶
package main import ( "encoding/json" "fmt" "net/http" "strconv" "github.com/gorilla/mux" "github.com/swaggest/openapi-go" "github.com/swaggest/openapi-go/openapi3" "github.com/swaggest/rest" "github.com/swaggest/rest/gorillamux" "github.com/swaggest/rest/nethttp" "github.com/swaggest/rest/request" ) // Define request structure for your HTTP handler. type myRequest struct { Query1 int `query:"query1"` Path1 string `path:"path1"` Path2 int `path:"path2"` Header1 float64 `header:"X-Header-1"` FormData1 bool `formData:"formData1"` FormData2 string `formData:"formData2"` } type myResp struct { Sum float64 `json:"sum"` Concat string `json:"concat"` } func newMyHandler() *myHandler { decoderFactory := request.NewDecoderFactory() decoderFactory.ApplyDefaults = true decoderFactory.SetDecoderFunc(rest.ParamInPath, gorillamux.PathToURLValues) return &myHandler{ dec: decoderFactory.MakeDecoder(http.MethodPost, myRequest{}, nil), } } type myHandler struct { // Automated request decoding is not required to collect OpenAPI schema, // but it is good to have to establish a single source of truth and to simplify request reading. dec nethttp.RequestDecoder } func (m *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { var in myRequest if err := m.dec.Decode(r, &in, nil); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Serve request. out := myResp{ Sum: in.Header1 + float64(in.Path2) + float64(in.Query1), Concat: in.Path1 + in.FormData2 + strconv.FormatBool(in.FormData1), } j, err := json.Marshal(out) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } _, _ = w.Write(j) } // SetupOpenAPIOperation declares OpenAPI schema for the handler. func (m *myHandler) SetupOpenAPIOperation(oc openapi.OperationContext) error { oc.SetTags("My Tag") oc.SetSummary("My Summary") oc.SetDescription("This endpoint aggregates request in structured way.") oc.AddReqStructure(myRequest{}) oc.AddRespStructure(myResp{}) oc.AddRespStructure(nil, openapi.WithContentType("text/html"), openapi.WithHTTPStatus(http.StatusBadRequest)) oc.AddRespStructure(nil, openapi.WithContentType("text/html"), openapi.WithHTTPStatus(http.StatusInternalServerError)) return nil } func main() { // Your router does not need special instrumentation. router := mux.NewRouter() // If handler implements gorillamux.OpenAPIPreparer, it will contribute detailed information to OpenAPI document. router.Handle("/foo/{path1}/bar/{path2}", newMyHandler()).Methods(http.MethodGet) // If handler does not implement gorillamux.OpenAPIPreparer, it will be exposed as incomplete. router.Handle("/uninstrumented-handler/{path-item}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})).Methods(http.MethodPost) // Setup OpenAPI schema. refl := openapi3.NewReflector() refl.SpecSchema().SetTitle("Sample API") refl.SpecSchema().SetVersion("v1.2.3") refl.SpecSchema().SetDescription("This is an example.") // Walk the router with OpenAPI collector. c := gorillamux.NewOpenAPICollector(refl) _ = router.Walk(c.Walker) // Get the resulting schema. yml, _ := refl.Spec.MarshalYAML() fmt.Println(string(yml)) }
Output: openapi: 3.0.3 info: description: This is an example. title: Sample API version: v1.2.3 paths: /foo/{path1}/bar/{path2}: get: description: This endpoint aggregates request in structured way. parameters: - in: query name: query1 schema: type: integer - in: path name: path1 required: true schema: type: string - in: path name: path2 required: true schema: type: integer - in: header name: X-Header-1 schema: type: number responses: "200": content: application/json: schema: $ref: '#/components/schemas/GorillamuxTestMyResp' description: OK "400": content: text/html: schema: type: string description: Bad Request "500": content: text/html: schema: type: string description: Internal Server Error summary: My Summary tags: - My Tag /uninstrumented-handler/{path-item}: post: description: Information about this operation was obtained using only HTTP method and path pattern. It may be incomplete and/or inaccurate. parameters: - in: path name: path-item required: true schema: type: string responses: "200": content: text/html: schema: type: string description: OK tags: - Incomplete components: schemas: GorillamuxTestMyResp: properties: concat: type: string sum: type: number type: object
type OpenAPIPreparer ¶
type OpenAPIPreparer interface {
SetupOpenAPIOperation(oc oapi.OperationContext) error
}
OpenAPIPreparer defines http.Handler with OpenAPI information.
Click to show internal directories.
Click to hide internal directories.