diff --git a/cfg/merge.go b/cfg/merge.go index 5da490b..076b1d6 100644 --- a/cfg/merge.go +++ b/cfg/merge.go @@ -161,7 +161,7 @@ func (f FileInput) Merge(from FileInput) FileInput { return from } -// MergeTypesMaps Merge merges all properties from an ancestor TypeMap. +// MergeTypesMaps merges all properties from an ancestor TypeMap. func MergeTypesMaps(maps ...stringlist.StringMap) stringlist.StringMap { result := stringlist.StringMap{} diff --git a/foji/openapi/handler.go.tpl b/foji/openapi/handler.go.tpl index 958f4dd..0131080 100644 --- a/foji/openapi/handler.go.tpl +++ b/foji/openapi/handler.go.tpl @@ -12,8 +12,10 @@ {{ goToken (camel $param.Value.Name) -}} {{- if $.ParamIsOptionalType $param }} *{{ end }} {{ $.GetType $package $typeName $param.Value.Schema }}, {{- end -}} - {{- if isNotNil $body}} - {{- $type := $.GetType $package (print $op.OperationID " Request") $body.Schema }} body {{ $type -}} + {{- if $.OpHasExtension $op "x-raw-body" -}} + body io.ReadCloser + {{- else if not (empty $body) -}} + body {{ $.GetType $package (print $op.OperationID " Request") $body.Schema }} {{- end -}} ) ( {{- $response := $.GetOpHappyResponseType $package .RuntimeParams.op}} @@ -357,8 +359,10 @@ func (h OpenAPIHandlers) {{ pascal $op.OperationID}}(w http.ResponseWriter, r *h } {{- end}} - {{- $hasBody := not (empty $opBody)}} - {{- if $hasBody }} + {{- $hasBody := or (not (empty $opBody)) ($.OpHasExtension $op "x-raw-body" ) }} + {{- if $.OpHasExtension $op "x-raw-body" }} + body := r.Body + {{- else if not (empty $opBody) }} {{- $bodyType := $.GetType $package (print $op.OperationID " Request") $opBody.Schema}} {{- if $opBody.IsJson }} diff --git a/runtime/funcs.go b/runtime/funcs.go index 0c97432..b4d59f2 100644 --- a/runtime/funcs.go +++ b/runtime/funcs.go @@ -171,7 +171,7 @@ func ToSlice(vv ...any) any { return ss } -// Numbers numbers returns a slice of strings of the numbers start to end (inclusive). +// Numbers returns a slice of strings of the numbers start to end (inclusive). func Numbers(start, end int) stringlist.Strings { var ss stringlist.Strings diff --git a/tests/example/http_handler_gen.go b/tests/example/http_handler_gen.go index 89b0b20..8cca784 100644 --- a/tests/example/http_handler_gen.go +++ b/tests/example/http_handler_gen.go @@ -4,6 +4,7 @@ package example import ( "context" + "io" "net/http" "time" @@ -41,6 +42,7 @@ type Operations interface { NoResponse(ctx context.Context, body Foo) error GetExampleOptional(ctx context.Context, k1 *string, k2 *uuid.UUID, k3 *time.Time, k4 *int32, k5 *int64, k5Default int64) (*Example, error) GetExampleQuery(ctx context.Context, k1 string, k2 uuid.UUID, k3 time.Time, k4 int32, k5 int64, k6 []string, k7 []uuid.UUID) (*Example, error) + GetRawBody(ctx context.Context, body io.ReadCloser) (*Example, error) GetRawRequest(r *http.Request, vehicle GetRawRequestVehicle) (*Example, error) GetRawRequestResponse(r *http.Request, w http.ResponseWriter, vehicle GetRawRequestResponseVehicle) (*Example, error) GetRawRequestResponseAndHeaders(r *http.Request, w http.ResponseWriter, vehicle GetRawRequestResponseAndHeadersVehicle) (*Example, http.Header, error) @@ -124,6 +126,7 @@ func RegisterHTTP(ops Operations, r Mux, bearerAuth TokenAuthenticator, customHe r.Handle("POST /examples/noResponse", http.HandlerFunc(s.NoResponse)) r.Handle("GET /examples/optional", http.HandlerFunc(s.GetExampleOptional)) r.Handle("GET /examples/query", http.HandlerFunc(s.GetExampleQuery)) + r.Handle("GET /examples/rawBody", http.HandlerFunc(s.GetRawBody)) r.Handle("GET /examples/rawRequest", http.HandlerFunc(s.GetRawRequest)) r.Handle("GET /examples/rawRequestResponse", http.HandlerFunc(s.GetRawRequestResponse)) r.Handle("GET /examples/rawRequestResponseAndHeaders", http.HandlerFunc(s.GetRawRequestResponseAndHeaders)) @@ -682,6 +685,23 @@ func (h OpenAPIHandlers) GetExampleQuery(w http.ResponseWriter, r *http.Request) httputil.JSONWrite(w, r, 200, response) } +// GetRawBody +func (h OpenAPIHandlers) GetRawBody(w http.ResponseWriter, r *http.Request) { + var err error + + logctx.AddStrToContext(r.Context(), "op", "getRawBody") + body := r.Body + + response, err := h.ops.GetRawBody(r.Context(), body) + if err != nil { + httputil.ErrorHandler(w, r, err) + + return + } + + httputil.JSONWrite(w, r, 200, response) +} + // GetRawRequest func (h OpenAPIHandlers) GetRawRequest(w http.ResponseWriter, r *http.Request) { var err error diff --git a/tests/example/openapi.yaml b/tests/example/openapi.yaml index 5a37d56..1187386 100644 --- a/tests/example/openapi.yaml +++ b/tests/example/openapi.yaml @@ -218,6 +218,22 @@ paths: application/json: schema: $ref: "#/components/schemas/Example" + /examples/rawBody: + get: + operationId: getRawBody + x-raw-body: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Foo' + responses: + "200": + description: 'Example' + content: + application/json: + schema: + $ref: "#/components/schemas/Example" /examples/rawResponse: get: operationId: getRawResponse diff --git a/tests/example/service.go b/tests/example/service.go index 4928aed..ed0dea8 100644 --- a/tests/example/service.go +++ b/tests/example/service.go @@ -2,6 +2,7 @@ package example import ( "context" + "io" "net/http" "time" @@ -74,6 +75,10 @@ func (s *Service) GetRawRequest(r *http.Request, vehicle GetRawRequestVehicle) ( return nil, nil } +func (s *Service) GetRawBody(ctx context.Context, body io.ReadCloser) (*Example, error) { + return nil, nil +} + func (s *Service) GetRawResponse(ctx context.Context, w http.ResponseWriter, vehicle GetRawResponseVehicle) (*Example, error) { return nil, nil }