From 544e349d9fe8b6a70484550635799ddabbfa3778 Mon Sep 17 00:00:00 2001 From: blackdahila Date: Thu, 26 Apr 2018 02:51:14 +0200 Subject: [PATCH] Support delete method in swagger generator (#616) --- examples/clients/echo/echo_service_api.go | 62 +++++++++++++++++++ examples/proto/examplepb/echo_service.pb.go | 46 ++++++++++++-- .../proto/examplepb/echo_service.pb.gw.go | 50 +++++++++++++++ examples/proto/examplepb/echo_service.proto | 6 ++ .../proto/examplepb/echo_service.swagger.json | 33 ++++++++++ examples/server/echo.go | 5 ++ protoc-gen-swagger/genswagger/template.go | 2 +- 7 files changed, 198 insertions(+), 6 deletions(-) diff --git a/examples/clients/echo/echo_service_api.go b/examples/clients/echo/echo_service_api.go index 1f562327d3d..41316dce169 100644 --- a/examples/clients/echo/echo_service_api.go +++ b/examples/clients/echo/echo_service_api.go @@ -222,3 +222,65 @@ func (a EchoServiceApi) EchoBody(body ExamplepbSimpleMessage) (*ExamplepbSimpleM return successPayload, localVarAPIResponse, err } +/** + * EchoDelete method receives a simple message and returns it. + * + * @param id Id represents the message identifier. + * @param num + * @return *ExamplepbSimpleMessage + */ +func (a EchoServiceApi) EchoDelete(id string, num string) (*ExamplepbSimpleMessage, *APIResponse, error) { + + var localVarHttpMethod = strings.ToUpper("Delete") + // create path and map variables + localVarPath := a.Configuration.BasePath + "/v1/example/echo_delete" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := make(map[string]string) + var localVarPostBody interface{} + var localVarFileName string + var localVarFileBytes []byte + // add default headers if any + for key := range a.Configuration.DefaultHeader { + localVarHeaderParams[key] = a.Configuration.DefaultHeader[key] + } + localVarQueryParams.Add("id", a.Configuration.APIClient.ParameterToString(id, "")) + localVarQueryParams.Add("num", a.Configuration.APIClient.ParameterToString(num, "")) + + // to determine the Content-Type header + localVarHttpContentTypes := []string{ "application/json", } + + // set Content-Type header + localVarHttpContentType := a.Configuration.APIClient.SelectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + // to determine the Accept header + localVarHttpHeaderAccepts := []string{ + "application/json", + } + + // set Accept header + localVarHttpHeaderAccept := a.Configuration.APIClient.SelectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + var successPayload = new(ExamplepbSimpleMessage) + localVarHttpResponse, err := a.Configuration.APIClient.CallAPI(localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + + var localVarURL, _ = url.Parse(localVarPath) + localVarURL.RawQuery = localVarQueryParams.Encode() + var localVarAPIResponse = &APIResponse{Operation: "EchoDelete", Method: localVarHttpMethod, RequestURL: localVarURL.String()} + if localVarHttpResponse != nil { + localVarAPIResponse.Response = localVarHttpResponse.RawResponse + localVarAPIResponse.Payload = localVarHttpResponse.Body() + } + + if err != nil { + return successPayload, localVarAPIResponse, err + } + err = json.Unmarshal(localVarHttpResponse.Body(), &successPayload) + return successPayload, localVarAPIResponse, err +} + diff --git a/examples/proto/examplepb/echo_service.pb.go b/examples/proto/examplepb/echo_service.pb.go index 1e1d349d311..a5d16e85ff1 100644 --- a/examples/proto/examplepb/echo_service.pb.go +++ b/examples/proto/examplepb/echo_service.pb.go @@ -99,6 +99,8 @@ type EchoServiceClient interface { Echo(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) // EchoBody method receives a simple message and returns it. EchoBody(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) + // EchoDelete method receives a simple message and returns it. + EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) } type echoServiceClient struct { @@ -127,6 +129,15 @@ func (c *echoServiceClient) EchoBody(ctx context.Context, in *SimpleMessage, opt return out, nil } +func (c *echoServiceClient) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) { + out := new(SimpleMessage) + err := grpc.Invoke(ctx, "/grpc.gateway.examples.examplepb.EchoService/EchoDelete", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for EchoService service type EchoServiceServer interface { @@ -137,6 +148,8 @@ type EchoServiceServer interface { Echo(context.Context, *SimpleMessage) (*SimpleMessage, error) // EchoBody method receives a simple message and returns it. EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error) + // EchoDelete method receives a simple message and returns it. + EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error) } func RegisterEchoServiceServer(s *grpc.Server, srv EchoServiceServer) { @@ -179,6 +192,24 @@ func _EchoService_EchoBody_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _EchoService_EchoDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SimpleMessage) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EchoServiceServer).EchoDelete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.gateway.examples.examplepb.EchoService/EchoDelete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EchoServiceServer).EchoDelete(ctx, req.(*SimpleMessage)) + } + return interceptor(ctx, in, info, handler) +} + var _EchoService_serviceDesc = grpc.ServiceDesc{ ServiceName: "grpc.gateway.examples.examplepb.EchoService", HandlerType: (*EchoServiceServer)(nil), @@ -191,6 +222,10 @@ var _EchoService_serviceDesc = grpc.ServiceDesc{ MethodName: "EchoBody", Handler: _EchoService_EchoBody_Handler, }, + { + MethodName: "EchoDelete", + Handler: _EchoService_EchoDelete_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "examples/proto/examplepb/echo_service.proto", @@ -199,7 +234,7 @@ var _EchoService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("examples/proto/examplepb/echo_service.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 260 bytes of a gzipped FileDescriptorProto + // 288 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0xad, 0x48, 0xcc, 0x2d, 0xc8, 0x49, 0x2d, 0xd6, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0xd7, 0x87, 0x72, 0x0b, 0x92, 0xf4, 0x53, 0x93, 0x33, 0xf2, 0xe3, 0x8b, 0x53, 0x8b, 0xca, 0x32, 0x93, 0x53, 0xf5, 0xc0, 0x92, 0x42, @@ -208,13 +243,14 @@ var fileDescriptor0 = []byte{ 0x89, 0x79, 0x79, 0xf9, 0x25, 0x89, 0x25, 0x99, 0xf9, 0x79, 0xc5, 0x10, 0xed, 0x4a, 0x86, 0x5c, 0xbc, 0xc1, 0x99, 0x20, 0x95, 0xbe, 0xa9, 0xc5, 0xc5, 0x89, 0xe9, 0xa9, 0x42, 0x7c, 0x5c, 0x4c, 0x99, 0x29, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x4c, 0x99, 0x29, 0x42, 0x02, 0x5c, 0xcc, - 0x79, 0xa5, 0xb9, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x20, 0xa6, 0xd1, 0x61, 0x26, 0x2e, + 0x79, 0xa5, 0xb9, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x20, 0xa6, 0xd1, 0x65, 0x66, 0x2e, 0x6e, 0xd7, 0xe4, 0x8c, 0xfc, 0x60, 0x88, 0x3b, 0x84, 0x96, 0x30, 0x72, 0xb1, 0x80, 0xf8, 0x42, 0x7a, 0x7a, 0x04, 0xdc, 0xa2, 0x87, 0x62, 0x95, 0x14, 0x89, 0xea, 0x95, 0x6c, 0x9a, 0x2e, 0x3f, 0x99, 0xcc, 0x64, 0xa6, 0x24, 0xaa, 0x5f, 0x66, 0x08, 0x0b, 0x14, 0x70, 0x90, 0xe8, 0x57, 0x67, 0xa6, 0xd4, 0x46, 0xc9, 0x0a, 0x49, 0x63, 0x95, 0xd0, 0xaf, 0xce, 0x2b, 0xcd, 0xad, 0x15, 0xea, 0x61, 0xe4, 0xe2, 0x00, 0x39, 0xd3, 0x29, 0x3f, 0xa5, 0x92, 0xe6, 0x4e, 0x55, 0x00, 0x3b, 0x55, - 0x0a, 0xd3, 0xa9, 0xf1, 0x49, 0xf9, 0x29, 0x95, 0x56, 0x8c, 0x5a, 0x4e, 0xdc, 0x51, 0x9c, 0x70, - 0xcd, 0x49, 0x6c, 0xe0, 0xc8, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x5b, 0xa7, 0x3a, 0x94, - 0xfa, 0x01, 0x00, 0x00, + 0x0a, 0xd3, 0xa9, 0xf1, 0x49, 0xf9, 0x29, 0x95, 0x56, 0x8c, 0x5a, 0x42, 0xbd, 0x8c, 0x5c, 0x5c, + 0x20, 0xe7, 0xb8, 0xa4, 0xe6, 0xa4, 0x96, 0xa4, 0xd2, 0xdc, 0x41, 0xf2, 0x60, 0x07, 0x49, 0x6a, + 0x89, 0x63, 0x38, 0x28, 0x05, 0xec, 0x00, 0x27, 0xee, 0x28, 0x4e, 0xb8, 0xde, 0x24, 0x36, 0x70, + 0xe2, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x46, 0x53, 0x05, 0xe1, 0x8a, 0x02, 0x00, 0x00, } diff --git a/examples/proto/examplepb/echo_service.pb.gw.go b/examples/proto/examplepb/echo_service.pb.gw.go index 4b6f8b1dacb..c281543bedb 100644 --- a/examples/proto/examplepb/echo_service.pb.gw.go +++ b/examples/proto/examplepb/echo_service.pb.gw.go @@ -114,6 +114,23 @@ func request_EchoService_EchoBody_0(ctx context.Context, marshaler runtime.Marsh } +var ( + filter_EchoService_EchoDelete_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_EchoService_EchoDelete_0(ctx context.Context, marshaler runtime.Marshaler, client EchoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SimpleMessage + var metadata runtime.ServerMetadata + + if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_EchoService_EchoDelete_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.EchoDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + // RegisterEchoServiceHandlerFromEndpoint is same as RegisterEchoServiceHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterEchoServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { @@ -239,6 +256,35 @@ func RegisterEchoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("DELETE", pattern_EchoService_EchoDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_EchoService_EchoDelete_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_EchoService_EchoDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -248,6 +294,8 @@ var ( pattern_EchoService_Echo_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "example", "echo", "id", "num"}, "")) pattern_EchoService_EchoBody_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_body"}, "")) + + pattern_EchoService_EchoDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "example", "echo_delete"}, "")) ) var ( @@ -256,4 +304,6 @@ var ( forward_EchoService_Echo_1 = runtime.ForwardResponseMessage forward_EchoService_EchoBody_0 = runtime.ForwardResponseMessage + + forward_EchoService_EchoDelete_0 = runtime.ForwardResponseMessage ) diff --git a/examples/proto/examplepb/echo_service.proto b/examples/proto/examplepb/echo_service.proto index 0a7a6fa7f49..506917c11c1 100644 --- a/examples/proto/examplepb/echo_service.proto +++ b/examples/proto/examplepb/echo_service.proto @@ -37,4 +37,10 @@ service EchoService { body: "*" }; } + // EchoDelete method receives a simple message and returns it. + rpc EchoDelete(SimpleMessage) returns (SimpleMessage) { + option (google.api.http) = { + delete: "/v1/example/echo_delete" + }; + } } diff --git a/examples/proto/examplepb/echo_service.swagger.json b/examples/proto/examplepb/echo_service.swagger.json index cf617932212..f76f9289a81 100644 --- a/examples/proto/examplepb/echo_service.swagger.json +++ b/examples/proto/examplepb/echo_service.swagger.json @@ -101,6 +101,39 @@ "EchoService" ] } + }, + "/v1/example/echo_delete": { + "delete": { + "summary": "EchoDelete method receives a simple message and returns it.", + "operationId": "EchoDelete", + "responses": { + "200": { + "description": "", + "schema": { + "$ref": "#/definitions/examplepbSimpleMessage" + } + } + }, + "parameters": [ + { + "name": "id", + "description": "Id represents the message identifier.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "num", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + } + ], + "tags": [ + "EchoService" + ] + } } }, "definitions": { diff --git a/examples/server/echo.go b/examples/server/echo.go index 1647c0aaa4c..249aeb0b211 100644 --- a/examples/server/echo.go +++ b/examples/server/echo.go @@ -34,3 +34,8 @@ func (s *echoServer) EchoBody(ctx context.Context, msg *examples.SimpleMessage) })) return msg, nil } + +func (s *echoServer) EchoDelete(ctx context.Context, msg *examples.SimpleMessage) (*examples.SimpleMessage, error) { + glog.Info(msg) + return msg, nil +} diff --git a/protoc-gen-swagger/genswagger/template.go b/protoc-gen-swagger/genswagger/template.go index 7c55d5367c9..d2b73e1ad6c 100644 --- a/protoc-gen-swagger/genswagger/template.go +++ b/protoc-gen-swagger/genswagger/template.go @@ -579,7 +579,7 @@ func renderServices(services []*descriptor.Service, paths swaggerPathsObject, re Required: true, Schema: &schema, }) - } else if b.HTTPMethod == "GET" { + } else if b.HTTPMethod == "GET" || b.HTTPMethod == "DELETE" { // add the parameters to the query string queryParams, err := messageToQueryParameters(meth.RequestType, reg, b.PathParams) if err != nil {