mirror of
https://github.com/go-kratos/kratos.git
synced 2025-01-07 23:02:12 +02:00
parent
f8eeb9f388
commit
946e9ca814
18
.github/workflows/go.yml
vendored
18
.github/workflows/go.yml
vendored
@ -23,3 +23,21 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
run: go test -v ./...
|
||||
|
||||
- name: Kratos
|
||||
run: |
|
||||
cd cmd/kratos
|
||||
go build ./...
|
||||
go test ./...
|
||||
|
||||
- name: HTTP
|
||||
run: |
|
||||
cd cmd/protoc-gen-go-http
|
||||
go build ./...
|
||||
go test ./...
|
||||
|
||||
- name: Errors
|
||||
run: |
|
||||
cd cmd/protoc-gen-go-errors
|
||||
go build ./...
|
||||
go test ./...
|
||||
|
@ -3,7 +3,7 @@ module github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/go-kratos/kratos/v2 v2.0.0-alpha5
|
||||
github.com/go-kratos/kratos/v2 v2.0.0-20210305104106-278210c4755a
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/gorilla/mux v1.8.0
|
||||
google.golang.org/genproto v0.0.0-20210202153253-cf70463f6119
|
||||
|
@ -491,7 +491,7 @@ var file_echo_service_proto_rawDesc = []byte{
|
||||
0x4d, 0x41, 0x47, 0x45, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c,
|
||||
0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x45, 0x57, 0x53, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08,
|
||||
0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x53, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49,
|
||||
0x44, 0x45, 0x4f, 0x10, 0x06, 0x32, 0xbc, 0x04, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65,
|
||||
0x44, 0x45, 0x4f, 0x10, 0x06, 0x32, 0xcc, 0x05, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xf2, 0x01, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x18,
|
||||
0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70,
|
||||
@ -513,13 +513,22 @@ var file_echo_service_proto_rawDesc = []byte{
|
||||
0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x1a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
|
||||
0x65, 0x63, 0x68, 0x6f, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x61, 0x0a, 0x0a,
|
||||
0x45, 0x63, 0x68, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73,
|
||||
0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1f,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
|
||||
0x65, 0x63, 0x68, 0x6f, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x82, 0x01, 0x0a,
|
||||
0x10, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64,
|
||||
0x79, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79,
|
||||
0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44,
|
||||
0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x22, 0x1e, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x72, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x62, 0x04, 0x62, 0x6f, 0x64,
|
||||
0x79, 0x12, 0x6c, 0x0a, 0x0a, 0x45, 0x63, 0x68, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
|
||||
0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x64, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x12,
|
||||
0x73, 0x0a, 0x09, 0x45, 0x63, 0x68, 0x6f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x74,
|
||||
0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x1f, 0x2e,
|
||||
@ -569,14 +578,16 @@ var file_echo_service_proto_depIdxs = []int32{
|
||||
7, // 6: testproto.DynamicMessageUpdate.update_mask:type_name -> google.protobuf.FieldMask
|
||||
2, // 7: testproto.EchoService.Echo:input_type -> testproto.SimpleMessage
|
||||
2, // 8: testproto.EchoService.EchoBody:input_type -> testproto.SimpleMessage
|
||||
2, // 9: testproto.EchoService.EchoDelete:input_type -> testproto.SimpleMessage
|
||||
4, // 10: testproto.EchoService.EchoPatch:input_type -> testproto.DynamicMessageUpdate
|
||||
2, // 11: testproto.EchoService.Echo:output_type -> testproto.SimpleMessage
|
||||
2, // 12: testproto.EchoService.EchoBody:output_type -> testproto.SimpleMessage
|
||||
2, // 13: testproto.EchoService.EchoDelete:output_type -> testproto.SimpleMessage
|
||||
4, // 14: testproto.EchoService.EchoPatch:output_type -> testproto.DynamicMessageUpdate
|
||||
11, // [11:15] is the sub-list for method output_type
|
||||
7, // [7:11] is the sub-list for method input_type
|
||||
4, // 9: testproto.EchoService.EchoResponseBody:input_type -> testproto.DynamicMessageUpdate
|
||||
2, // 10: testproto.EchoService.EchoDelete:input_type -> testproto.SimpleMessage
|
||||
4, // 11: testproto.EchoService.EchoPatch:input_type -> testproto.DynamicMessageUpdate
|
||||
2, // 12: testproto.EchoService.Echo:output_type -> testproto.SimpleMessage
|
||||
2, // 13: testproto.EchoService.EchoBody:output_type -> testproto.SimpleMessage
|
||||
4, // 14: testproto.EchoService.EchoResponseBody:output_type -> testproto.DynamicMessageUpdate
|
||||
2, // 15: testproto.EchoService.EchoDelete:output_type -> testproto.SimpleMessage
|
||||
4, // 16: testproto.EchoService.EchoPatch:output_type -> testproto.DynamicMessageUpdate
|
||||
12, // [12:17] is the sub-list for method output_type
|
||||
7, // [7:12] is the sub-list for method input_type
|
||||
7, // [7:7] is the sub-list for extension type_name
|
||||
7, // [7:7] is the sub-list for extension extendee
|
||||
0, // [0:7] is the sub-list for field type_name
|
||||
|
@ -85,10 +85,17 @@ service EchoService {
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
// EchoResponseBody method receives a simple message and returns it.
|
||||
rpc EchoResponseBody(DynamicMessageUpdate) returns (DynamicMessageUpdate) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/example/echo_response_body"
|
||||
response_body: "body"
|
||||
};
|
||||
}
|
||||
// EchoDelete method receives a simple message and returns it.
|
||||
rpc EchoDelete(SimpleMessage) returns (SimpleMessage) {
|
||||
option (google.api.http) = {
|
||||
delete: "/v1/example/echo_delete"
|
||||
delete: "/v1/example/echo_delete/{id}/{num}"
|
||||
};
|
||||
}
|
||||
// EchoPatch method receives a NonStandardUpdateRequest and returns it.
|
||||
|
@ -25,6 +25,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)
|
||||
// EchoResponseBody method receives a simple message and returns it.
|
||||
EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate, opts ...grpc.CallOption) (*DynamicMessageUpdate, error)
|
||||
// EchoDelete method receives a simple message and returns it.
|
||||
EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error)
|
||||
// EchoPatch method receives a NonStandardUpdateRequest and returns it.
|
||||
@ -57,6 +59,15 @@ func (c *echoServiceClient) EchoBody(ctx context.Context, in *SimpleMessage, opt
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *echoServiceClient) EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate, opts ...grpc.CallOption) (*DynamicMessageUpdate, error) {
|
||||
out := new(DynamicMessageUpdate)
|
||||
err := c.cc.Invoke(ctx, "/testproto.EchoService/EchoResponseBody", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *echoServiceClient) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) {
|
||||
out := new(SimpleMessage)
|
||||
err := c.cc.Invoke(ctx, "/testproto.EchoService/EchoDelete", in, out, opts...)
|
||||
@ -86,6 +97,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)
|
||||
// EchoResponseBody method receives a simple message and returns it.
|
||||
EchoResponseBody(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error)
|
||||
// EchoDelete method receives a simple message and returns it.
|
||||
EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error)
|
||||
// EchoPatch method receives a NonStandardUpdateRequest and returns it.
|
||||
@ -103,6 +116,9 @@ func (UnimplementedEchoServiceServer) Echo(context.Context, *SimpleMessage) (*Si
|
||||
func (UnimplementedEchoServiceServer) EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method EchoBody not implemented")
|
||||
}
|
||||
func (UnimplementedEchoServiceServer) EchoResponseBody(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method EchoResponseBody not implemented")
|
||||
}
|
||||
func (UnimplementedEchoServiceServer) EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method EchoDelete not implemented")
|
||||
}
|
||||
@ -158,6 +174,24 @@ func _EchoService_EchoBody_Handler(srv interface{}, ctx context.Context, dec fun
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _EchoService_EchoResponseBody_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DynamicMessageUpdate)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(EchoServiceServer).EchoResponseBody(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/testproto.EchoService/EchoResponseBody",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(EchoServiceServer).EchoResponseBody(ctx, req.(*DynamicMessageUpdate))
|
||||
}
|
||||
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 {
|
||||
@ -209,6 +243,10 @@ var EchoService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "EchoBody",
|
||||
Handler: _EchoService_EchoBody_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "EchoResponseBody",
|
||||
Handler: _EchoService_EchoResponseBody_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "EchoDelete",
|
||||
Handler: _EchoService_EchoDelete_Handler,
|
||||
|
@ -27,6 +27,8 @@ type EchoServiceHandler interface {
|
||||
EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error)
|
||||
|
||||
EchoPatch(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error)
|
||||
|
||||
EchoResponseBody(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error)
|
||||
}
|
||||
|
||||
func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) http.Handler {
|
||||
@ -38,16 +40,16 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
|
||||
r.HandleFunc("/v1/example/echo/{id}/{num}", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.Echo(ctx, req.(*SimpleMessage))
|
||||
}
|
||||
@ -59,23 +61,24 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*SimpleMessage)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("GET")
|
||||
|
||||
r.HandleFunc("/v1/example/echo/{id}/{num}/{lang}", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.Echo(ctx, req.(*SimpleMessage))
|
||||
}
|
||||
@ -87,23 +90,24 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*SimpleMessage)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("GET")
|
||||
|
||||
r.HandleFunc("/v1/example/echo1/{id}/{line_num}/{status.note}", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.Echo(ctx, req.(*SimpleMessage))
|
||||
}
|
||||
@ -115,23 +119,24 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*SimpleMessage)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("GET")
|
||||
|
||||
r.HandleFunc("/v1/example/echo2/{no.note}", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.Echo(ctx, req.(*SimpleMessage))
|
||||
}
|
||||
@ -143,23 +148,24 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*SimpleMessage)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("GET")
|
||||
|
||||
r.HandleFunc("/v1/example/echo/{id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.Echo(ctx, req.(*SimpleMessage))
|
||||
}
|
||||
@ -171,18 +177,19 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*SimpleMessage)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("POST")
|
||||
|
||||
r.HandleFunc("/v1/example/echo_body", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.EchoBody(ctx, req.(*SimpleMessage))
|
||||
}
|
||||
@ -194,18 +201,48 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*SimpleMessage)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("POST")
|
||||
|
||||
r.HandleFunc("/v1/example/echo_delete", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
|
||||
r.HandleFunc("/v1/example/echo_response_body", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in DynamicMessageUpdate
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.EchoResponseBody(ctx, req.(*DynamicMessageUpdate))
|
||||
}
|
||||
if h.Middleware != nil {
|
||||
next = h.Middleware(next)
|
||||
}
|
||||
out, err := next(r.Context(), &in)
|
||||
if err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
reply := out.(*DynamicMessageUpdate)
|
||||
if err := h.Encode(w, r, reply.Body); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("POST")
|
||||
|
||||
r.HandleFunc("/v1/example/echo_delete/{id}/{num}", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in SimpleMessage
|
||||
if err := h.Decode(r, &in); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.EchoDelete(ctx, req.(*SimpleMessage))
|
||||
}
|
||||
@ -217,18 +254,19 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*SimpleMessage)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("DELETE")
|
||||
|
||||
r.HandleFunc("/v1/example/echo_patch", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in DynamicMessageUpdate
|
||||
|
||||
if err := h.Decode(r, &in.Body); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.EchoPatch(ctx, req.(*DynamicMessageUpdate))
|
||||
}
|
||||
@ -240,7 +278,8 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out); err != nil {
|
||||
reply := out.(*DynamicMessageUpdate)
|
||||
if err := h.Encode(w, r, reply); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("PATCH")
|
||||
|
212
cmd/protoc-gen-go-http/internal/testproto/echo_service_test.go
Normal file
212
cmd/protoc-gen-go-http/internal/testproto/echo_service_test.go
Normal file
@ -0,0 +1,212 @@
|
||||
package testproto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
context "context"
|
||||
"fmt"
|
||||
"net"
|
||||
http "net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
tr "github.com/go-kratos/kratos/v2/transport/http"
|
||||
_struct "github.com/golang/protobuf/ptypes/struct"
|
||||
)
|
||||
|
||||
type echoService struct {
|
||||
}
|
||||
|
||||
func (s *echoService) Echo(ctx context.Context, m *SimpleMessage) (*SimpleMessage, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (s *echoService) EchoBody(ctx context.Context, m *SimpleMessage) (*SimpleMessage, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (s *echoService) EchoDelete(ctx context.Context, m *SimpleMessage) (*SimpleMessage, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (s *echoService) EchoPatch(ctx context.Context, m *DynamicMessageUpdate) (*DynamicMessageUpdate, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (s *echoService) EchoResponseBody(ctx context.Context, m *DynamicMessageUpdate) (*DynamicMessageUpdate, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
type echoClient struct {
|
||||
baseURL string
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
// post: /v1/example/echo/{id}
|
||||
func (c *echoClient) Echo(ctx context.Context, in *SimpleMessage) (out *SimpleMessage, err error) {
|
||||
codec := encoding.GetCodec("json")
|
||||
data, err := codec.Marshal(in)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s/v1/example/echo/%s", c.baseURL, in.Id), bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.Header.Set("content-type", "application/json")
|
||||
out = new(SimpleMessage)
|
||||
if err = tr.Do(c.client, req, out); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// post: /v1/example/echo_body
|
||||
func (c *echoClient) EchoBody(ctx context.Context, in *SimpleMessage) (out *SimpleMessage, err error) {
|
||||
codec := encoding.GetCodec("json")
|
||||
data, err := codec.Marshal(in)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s/v1/example/echo_body", c.baseURL), bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.Header.Set("content-type", "application/json")
|
||||
out = new(SimpleMessage)
|
||||
if err = tr.Do(c.client, req, out); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// delete: /v1/example/echo_delete/{id}/{num}
|
||||
func (c *echoClient) EchoDelete(ctx context.Context, in *SimpleMessage) (out *SimpleMessage, err error) {
|
||||
req, err := http.NewRequest("DELETE", fmt.Sprintf("%s/v1/example/echo_delete/%s/%d", c.baseURL, in.Id, in.Num), nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out = new(SimpleMessage)
|
||||
if err = tr.Do(c.client, req, out); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// patch: /v1/example/echo_patch
|
||||
func (c *echoClient) EchoPatch(ctx context.Context, in *DynamicMessageUpdate) (out *DynamicMessageUpdate, err error) {
|
||||
codec := encoding.GetCodec("json")
|
||||
data, err := codec.Marshal(in.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req, err := http.NewRequest("PATCH", fmt.Sprintf("%s/v1/example/echo_patch", c.baseURL), bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.Header.Set("content-type", "application/json")
|
||||
out = new(DynamicMessageUpdate)
|
||||
if err = tr.Do(c.client, req, out); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// post: /v1/example/echo_response_body
|
||||
func (c *echoClient) EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate) (out *DynamicMessageUpdate, err error) {
|
||||
codec := encoding.GetCodec("json")
|
||||
data, err := codec.Marshal(in)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s/v1/example/echo_response_body", c.baseURL), bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
req.Header.Set("content-type", "application/json")
|
||||
out = new(DynamicMessageUpdate)
|
||||
if err = tr.Do(c.client, req, out.Body); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func TestEchoService(t *testing.T) {
|
||||
s := &echoService{}
|
||||
h := NewEchoServiceHandler(s)
|
||||
srv := &http.Server{Addr: ":0", Handler: h}
|
||||
lis, err := net.Listen("tcp", srv.Addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
addr := lis.Addr().(*net.TCPAddr)
|
||||
time.AfterFunc(time.Second, func() {
|
||||
defer srv.Shutdown(context.Background())
|
||||
testEchoClient(t, fmt.Sprintf("http://127.0.0.1:%d", addr.Port))
|
||||
})
|
||||
if err := srv.Serve(lis); err != nil && err != http.ErrServerClosed {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testEchoClient(t *testing.T, baseURL string) {
|
||||
var (
|
||||
err error
|
||||
in = &SimpleMessage{Id: "test_id", Num: 100}
|
||||
out = &SimpleMessage{}
|
||||
)
|
||||
check := func(in, out *SimpleMessage) {
|
||||
if in.Id != out.Id || in.Num != out.Num {
|
||||
t.Errorf("expected %s got %s", in, out)
|
||||
}
|
||||
}
|
||||
|
||||
cli := &echoClient{baseURL: baseURL, client: http.DefaultClient}
|
||||
|
||||
if out, err = cli.Echo(context.Background(), in); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
check(in, out)
|
||||
|
||||
if out, err = cli.EchoBody(context.Background(), in); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
check(in, out)
|
||||
|
||||
if out, err = cli.EchoDelete(context.Background(), in); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
check(in, out)
|
||||
|
||||
var (
|
||||
din = &DynamicMessageUpdate{Body: &DynamicMessage{
|
||||
ValueField: &_struct.Value{Kind: &_struct.Value_StringValue{StringValue: "test"}},
|
||||
}}
|
||||
dout *DynamicMessageUpdate
|
||||
)
|
||||
if dout, err = cli.EchoPatch(context.Background(), din); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if din.Body.ValueField.GetStringValue() != dout.Body.ValueField.GetStringValue() {
|
||||
t.Errorf("EchoPatch expected %s got %s", din, dout)
|
||||
}
|
||||
if dout, err = cli.EchoResponseBody(context.Background(), din); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if din.Body.ValueField.GetStringValue() != dout.Body.ValueField.GetStringValue() {
|
||||
t.Errorf("EchoResponseBody expected %s got %s", din, dout)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSON(t *testing.T) {
|
||||
in := &SimpleMessage{Id: "test_id", Num: 100}
|
||||
out := &SimpleMessage{}
|
||||
codec := encoding.GetCodec("json")
|
||||
data, err := codec.Marshal(in)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := codec.Unmarshal(data, out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
@ -22,16 +22,16 @@ func New{{.ServiceType}}Handler(srv {{.ServiceType}}Handler, opts ...http1.Handl
|
||||
{{range .Methods}}
|
||||
r.HandleFunc("{{.Path}}", func(w http.ResponseWriter, r *http.Request) {
|
||||
var in {{.Request}}
|
||||
if err := h.Decode(r, &in{{.Body}}); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
{{if ne (len .Vars) 0}}
|
||||
if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
{{end}}
|
||||
if err := h.Decode(r, &in{{.Body}}); err != nil {
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
next := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.{{.Name}}(ctx, req.(*{{.Request}}))
|
||||
}
|
||||
@ -43,7 +43,8 @@ func New{{.ServiceType}}Handler(srv {{.ServiceType}}Handler, opts ...http1.Handl
|
||||
h.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
if err := h.Encode(w, r, out{{.ResponseBody}}); err != nil {
|
||||
reply := out.(*{{.Reply}})
|
||||
if err := h.Encode(w, r, reply{{.ResponseBody}}); err != nil {
|
||||
h.Error(w, r, err)
|
||||
}
|
||||
}).Methods("{{.Method}}")
|
||||
|
@ -2,6 +2,7 @@ package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
|
||||
@ -21,6 +22,8 @@ var (
|
||||
UnmarshalOptions = protojson.UnmarshalOptions{
|
||||
DiscardUnknown: true,
|
||||
}
|
||||
|
||||
typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -38,6 +41,15 @@ func (codec) Marshal(v interface{}) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (codec) Unmarshal(data []byte, v interface{}) error {
|
||||
rv := reflect.ValueOf(v)
|
||||
for rv.Kind() == reflect.Ptr {
|
||||
if rv.IsNil() {
|
||||
rv.Set(reflect.New(rv.Type().Elem()))
|
||||
v = rv.Interface()
|
||||
break
|
||||
}
|
||||
rv = rv.Elem()
|
||||
}
|
||||
if m, ok := v.(proto.Message); ok {
|
||||
return UnmarshalOptions.Unmarshal(data, m)
|
||||
}
|
||||
|
@ -2,10 +2,11 @@ package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
"github.com/go-kratos/kratos/v2/errors"
|
||||
"github.com/go-kratos/kratos/v2/middleware"
|
||||
"github.com/go-kratos/kratos/v2/transport"
|
||||
@ -116,11 +117,24 @@ func Do(client *http.Client, req *http.Request, target interface{}) error {
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode < 200 || res.StatusCode > 299 {
|
||||
se := &errors.StatusError{}
|
||||
if err := json.NewDecoder(req.Body).Decode(se); err != nil {
|
||||
se := &errors.StatusError{Code: 2}
|
||||
if err := decodeResponse(res, se); err != nil {
|
||||
return err
|
||||
}
|
||||
return se
|
||||
}
|
||||
return json.NewDecoder(req.Body).Decode(target)
|
||||
return decodeResponse(res, target)
|
||||
}
|
||||
|
||||
func decodeResponse(res *http.Response, target interface{}) error {
|
||||
subtype := contentSubtype(res.Header.Get(contentTypeHeader))
|
||||
codec := encoding.GetCodec(subtype)
|
||||
if codec == nil {
|
||||
codec = encoding.GetCodec("json")
|
||||
}
|
||||
data, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return codec.Unmarshal(data, target)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
@ -96,18 +95,22 @@ func decodeRequest(req *http.Request, v interface{}) error {
|
||||
|
||||
// encodeResponse encodes the object to the HTTP response.
|
||||
func encodeResponse(w http.ResponseWriter, r *http.Request, v interface{}) error {
|
||||
var codec encoding.Codec
|
||||
for _, accept := range r.Header[acceptHeader] {
|
||||
if codec := encoding.GetCodec(contentSubtype(accept)); codec != nil {
|
||||
data, err := codec.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Header().Set(contentTypeHeader, contentType(codec.Name()))
|
||||
w.Write(data)
|
||||
return nil
|
||||
if codec = encoding.GetCodec(contentSubtype(accept)); codec != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return json.NewEncoder(w).Encode(v)
|
||||
if codec == nil {
|
||||
codec = encoding.GetCodec("json")
|
||||
}
|
||||
data, err := codec.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Header().Set(contentTypeHeader, contentType(codec.Name()))
|
||||
w.Write(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
// encodeError encodes the erorr to the HTTP response.
|
||||
@ -116,7 +119,6 @@ func encodeError(w http.ResponseWriter, r *http.Request, err error) {
|
||||
if !ok {
|
||||
se = &errors.StatusError{
|
||||
Code: 2,
|
||||
Reason: "",
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user