transport/http: add http route (#1029)

* add http route

* fix http context

* add HTTP middleware

Co-authored-by: longXboy <longxboyhi@gmail.com>
pull/1036/head
Tony Chen 3 years ago committed by GitHub
parent 4a257c1a34
commit 1b13abd136
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 124
      api/metadata/metadata_http.pb.go
  2. 39
      cmd/protoc-gen-go-errors/errors.go
  3. 10
      cmd/protoc-gen-go-http/http.go
  4. 90
      cmd/protoc-gen-go-http/template.go
  5. 6
      cmd/protoc-gen-go-http/version.go
  6. 80
      encoding/json/json_test.go
  7. 277
      examples/blog/api/blog/v1/blog_http.pb.go
  8. 134
      examples/blog/api/blog/v1/error_reason.pb.go
  9. 14
      examples/blog/api/blog/v1/error_reason.proto
  10. 6
      examples/blog/cmd/blog/main.go
  11. 4
      examples/blog/cmd/blog/wire_gen.go
  12. 4
      examples/blog/internal/server/grpc.go
  13. 19
      examples/blog/internal/server/http.go
  14. 77
      examples/helloworld/helloworld/helloworld_http.pb.go
  15. 20
      examples/helloworld/server/main.go
  16. 52
      examples/http/handler/main.go
  17. 28
      examples/http/middlewares/handlers.go
  18. 40
      examples/http/middlewares/main.go
  19. 75
      examples/http/middlewares/middlewares.go
  20. 25
      examples/http/middlewares/services.go
  21. 33
      examples/http/upload/main.go
  22. 16
      examples/metadata/server/main.go
  23. 380
      examples/proto/echo_service_http.pb.go
  24. 86
      examples/proto/stream.pb.go
  25. 18
      examples/registry/consul/server/main.go
  26. 77
      examples/traces/api/message/message_http.pb.go
  27. 77
      examples/traces/api/user/user_http.pb.go
  28. 32
      examples/traces/app/user/main.go
  29. 296
      internal/testproto/echo_service.pb.go
  30. 0
      internal/testproto/echo_service.proto
  31. 2
      internal/testproto/echo_service_grpc.pb.go
  32. 303
      internal/testproto/echo_service_http.pb.go
  33. 101
      internal/testproto/echo_service_test.go
  34. 3
      internal/testproto/generate.go
  35. 86
      internal/testproto/stream.pb.go
  36. 0
      internal/testproto/stream.proto
  37. 2
      internal/testproto/stream_grpc.pb.go
  38. 24
      middleware/logging/logging.go
  39. 22
      middleware/logging/logging_test.go
  40. 32
      middleware/metrics/metrics.go
  41. 4
      middleware/tracing/tracing.go
  42. 16
      transport/grpc/client.go
  43. 14
      transport/grpc/server.go
  44. 22
      transport/grpc/transport.go
  45. 6
      transport/http/binding/bind.go
  46. 6
      transport/http/binding/encode.go
  47. 8
      transport/http/binding/proto_test.go
  48. 20
      transport/http/calloption.go
  49. 16
      transport/http/client.go
  50. 89
      transport/http/codec.go
  51. 142
      transport/http/context.go
  52. 215
      transport/http/handle.go
  53. 24
      transport/http/handle_test.go
  54. 101
      transport/http/route.go
  55. 135
      transport/http/route_test.go
  56. 93
      transport/http/server.go
  57. 46
      transport/http/transport.go
  58. 25
      transport/transport.go

@ -1,4 +1,6 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// protoc-gen-go-http v2.0.0-rc3
package metadata
@ -6,126 +8,102 @@ import (
context "context"
middleware "github.com/go-kratos/kratos/v2/middleware"
transport "github.com/go-kratos/kratos/v2/transport"
http1 "github.com/go-kratos/kratos/v2/transport/http"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = new(middleware.Middleware)
var _ = new(transport.Transporter)
var _ = binding.BindVars
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
const _ = http.SupportPackageIsVersion1
type MetadataHandler interface {
type MetadataHTTPServer interface {
GetServiceDesc(context.Context, *GetServiceDescRequest) (*GetServiceDescReply, error)
ListServices(context.Context, *ListServicesRequest) (*ListServicesReply, error)
}
func NewMetadataHandler(srv MetadataHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
func RegisterMetadataHTTPServer(s *http.Server, srv MetadataHTTPServer) {
r := s.Route("/")
r.GET("/services", _Metadata_ListServices0_HTTP_Handler(srv))
r.GET("/services/{name}", _Metadata_GetServiceDesc0_HTTP_Handler(srv))
}
r.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
func _Metadata_ListServices0_HTTP_Handler(srv MetadataHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in ListServicesRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/kratos.api.Metadata/ListServices")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.ListServices(ctx, req.(*ListServicesRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/kratos.api.Metadata/ListServices")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*ListServicesReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return ctx.Result(200, reply)
}
}
r.HandleFunc("/services/{name}", func(w http.ResponseWriter, r *http.Request) {
func _Metadata_GetServiceDesc0_HTTP_Handler(srv MetadataHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in GetServiceDescRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/kratos.api.Metadata/GetServiceDesc")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetServiceDesc(ctx, req.(*GetServiceDescRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/kratos.api.Metadata/GetServiceDesc")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*GetServiceDescReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
return ctx.Result(200, reply)
}
}
type MetadataHTTPClient interface {
GetServiceDesc(ctx context.Context, req *GetServiceDescRequest, opts ...http1.CallOption) (rsp *GetServiceDescReply, err error)
ListServices(ctx context.Context, req *ListServicesRequest, opts ...http1.CallOption) (rsp *ListServicesReply, err error)
GetServiceDesc(ctx context.Context, req *GetServiceDescRequest, opts ...http.CallOption) (rsp *GetServiceDescReply, err error)
ListServices(ctx context.Context, req *ListServicesRequest, opts ...http.CallOption) (rsp *ListServicesReply, err error)
}
type MetadataHTTPClientImpl struct {
cc *http1.Client
cc *http.Client
}
func NewMetadataHTTPClient(client *http1.Client) MetadataHTTPClient {
func NewMetadataHTTPClient(client *http.Client) MetadataHTTPClient {
return &MetadataHTTPClientImpl{client}
}
func (c *MetadataHTTPClientImpl) GetServiceDesc(ctx context.Context, in *GetServiceDescRequest, opts ...http1.CallOption) (*GetServiceDescReply, error) {
func (c *MetadataHTTPClientImpl) GetServiceDesc(ctx context.Context, in *GetServiceDescRequest, opts ...http.CallOption) (*GetServiceDescReply, error) {
var out GetServiceDescReply
path := binding.EncodePath("GET", "/services/{name}", in)
opts = append(opts, http1.Method("/kratos.api.Metadata/GetServiceDesc"))
path := binding.EncodeVars("/services/{name}", in, true)
opts = append(opts, http.Operation("/kratos.api.Metadata/GetServiceDesc"))
err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *MetadataHTTPClientImpl) ListServices(ctx context.Context, in *ListServicesRequest, opts ...http1.CallOption) (*ListServicesReply, error) {
func (c *MetadataHTTPClientImpl) ListServices(ctx context.Context, in *ListServicesRequest, opts ...http.CallOption) (*ListServicesReply, error) {
var out ListServicesReply
path := binding.EncodePath("GET", "/services", in)
opts = append(opts, http1.Method("/kratos.api.Metadata/ListServices"))
path := binding.EncodeVars("/services", in, true)
opts = append(opts, http.Operation("/kratos.api.Metadata/ListServices"))
err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}

@ -15,7 +15,13 @@ const (
// generateFile generates a _http.pb.go file containing kratos errors definitions.
func generateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile {
if len(file.Enums) == 0 {
var hasCode bool
for _, enum := range file.Enums {
if code := defaultErrorCode(enum); code > 0 {
hasCode = true
}
}
if len(file.Enums) == 0 || !hasCode {
return nil
}
filename := file.GeneratedFilenamePrefix + "_errors.pb.go"
@ -44,36 +50,37 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.
}
}
func genErrorsReason(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, enum *protogen.Enum) {
func defaultErrorCode(enum *protogen.Enum) int {
defaultCode := proto.GetExtension(enum.Desc.Options(), errors.E_DefaultCode)
code := 0
if ok := defaultCode.(int32); ok != 0 && ok <= 600 && ok >= 200 {
code = int(ok)
} else {
return
if code, ok := defaultCode.(int32); ok && code > 0 {
return int(code)
}
return 0
}
func genErrorsReason(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, enum *protogen.Enum) {
var ew errorWrapper
defCode := defaultErrorCode(enum)
for _, v := range enum.Values {
eCode := proto.GetExtension(v.Desc.Options(), errors.E_Code)
enumCode := int(eCode.(int32))
if enumCode == 0 {
enumCode = code
code := int(proto.GetExtension(v.Desc.Options(), errors.E_Code).(int32))
if code == 0 {
code = defCode
}
if enumCode > 600 || enumCode < 200 {
return
if code > 600 || code < 200 {
panic("httpstatus code must be greater than or equal to 200 and less than 600")
}
err := &errorInfo{
Name: string(enum.Desc.Name()),
Value: string(v.Desc.Name()),
CamelValue: Case2Camel(string(v.Desc.Name())),
HttpCode: enumCode,
CamelValue: case2Camel(string(v.Desc.Name())),
HttpCode: code,
}
ew.Errors = append(ew.Errors, err)
}
g.P(ew.execute())
}
func Case2Camel(name string) string {
func case2Camel(name string) string {
if !strings.Contains(name, "_") {
return name
}

@ -1,6 +1,7 @@
package main
import (
"fmt"
"strings"
"google.golang.org/genproto/googleapis/api/annotations"
@ -11,8 +12,6 @@ import (
const (
contextPackage = protogen.GoImportPath("context")
httpPackage = protogen.GoImportPath("net/http")
muxPackage = protogen.GoImportPath("github.com/gorilla/mux")
middlewarePackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/middleware")
transportHTTPPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http")
bindingPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http/binding")
@ -29,6 +28,8 @@ func generateFile(gen *protogen.Plugin, file *protogen.File) *protogen.Generated
filename := file.GeneratedFilenamePrefix + "_http.pb.go"
g := gen.NewGeneratedFile(filename, file.GoImportPath)
g.P("// Code generated by protoc-gen-go-http. DO NOT EDIT.")
g.P("// versions:")
g.P(fmt.Sprintf("// protoc-gen-go-http %s", Version))
g.P()
g.P("package ", file.GoPackageName)
g.P()
@ -43,12 +44,10 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.
}
g.P("// This is a compile-time assertion to ensure that this generated file")
g.P("// is compatible with the kratos package it is being compiled against.")
g.P("var _ = new(", httpPackage.Ident("Request"), ")")
g.P("var _ = new(", contextPackage.Ident("Context"), ")")
g.P("var _ = new(", middlewarePackage.Ident("Middleware"), ")")
g.P("var _ = new(", transportPackage.Ident("Transporter"), ")")
g.P("var _ = ", bindingPackage.Ident("BindVars"))
g.P("var _ = ", muxPackage.Ident("NewRouter"))
g.P("const _ = ", transportHTTPPackage.Ident("SupportPackageIsVersion1"))
g.P()
@ -104,11 +103,13 @@ func buildHTTPRule(g *protogen.GeneratedFile, m *protogen.Method, rule *annotati
method string
body string
responseBody string
isQuery bool
)
switch pattern := rule.Pattern.(type) {
case *annotations.HttpRule_Get:
path = pattern.Get
method = "GET"
isQuery = true
case *annotations.HttpRule_Put:
path = pattern.Put
method = "PUT"
@ -142,6 +143,7 @@ func buildHTTPRule(g *protogen.GeneratedFile, m *protogen.Method, rule *annotati
} else if responseBody != "" {
md.ResponseBody = "." + camelCaseVars(responseBody)
}
md.IsQuery = isQuery
return md
}

@ -9,77 +9,72 @@ import (
var httpTemplate = `
{{$svrType := .ServiceType}}
{{$svrName := .ServiceName}}
type {{.ServiceType}}Handler interface {
{{range .MethodSets}}
type {{.ServiceType}}HTTPServer interface {
{{- range .MethodSets}}
{{.Name}}(context.Context, *{{.Request}}) (*{{.Reply}}, error)
{{end}}
{{- end}}
}
func New{{.ServiceType}}Handler(srv {{.ServiceType}}Handler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
{{range .Methods}}
r.HandleFunc("{{.Path}}", func(w http.ResponseWriter, r *http.Request) {
func Register{{.ServiceType}}HTTPServer(s *http.Server, srv {{.ServiceType}}HTTPServer) {
r := s.Route("/")
{{- range .Methods}}
r.{{.Method}}("{{.Path}}", _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv))
{{- end}}
}
{{range .Methods}}
func _{{$svrType}}_{{.Name}}{{.Num}}_HTTP_Handler(srv {{$svrType}}HTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in {{.Request}}
if err := h.Decode(r, &in{{.Body}}); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in{{.Body}}); err != nil {
return err
}
{{if ne (len .Vars) 0}}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
{{- if ne (len .Vars) 0}}
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
{{end}}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
{{- end}}
transport.SetOperation(ctx,"/{{$svrName}}/{{.Name}}")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.{{.Name}}(ctx, req.(*{{.Request}}))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx,"/{{$svrName}}/{{.Name}}")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*{{.Reply}})
if err := h.Encode(w, r, reply{{.ResponseBody}}); err != nil {
h.Error(w, r, err)
}
}).Methods("{{.Method}}")
{{end}}
return r
return ctx.Result(200, reply{{.ResponseBody}})
}
}
{{end}}
type {{.ServiceType}}HTTPClient interface {
{{range .MethodSets}}
{{.Name}}(ctx context.Context, req *{{.Request}}, opts ...http1.CallOption) (rsp *{{.Reply}}, err error)
{{end}}
{{- range .MethodSets}}
{{.Name}}(ctx context.Context, req *{{.Request}}, opts ...http.CallOption) (rsp *{{.Reply}}, err error)
{{- end}}
}
type {{.ServiceType}}HTTPClientImpl struct{
cc *http1.Client
cc *http.Client
}
func New{{.ServiceType}}HTTPClient (client *http1.Client) {{.ServiceType}}HTTPClient {
func New{{.ServiceType}}HTTPClient (client *http.Client) {{.ServiceType}}HTTPClient {
return &{{.ServiceType}}HTTPClientImpl{client}
}
{{range .MethodSets}}
func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http1.CallOption) (*{{.Reply}}, error) {
func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http.CallOption) (*{{.Reply}}, error) {
var out {{.Reply}}
path := binding.EncodePath("{{.Method}}", "{{.Path}}", in)
opts = append(opts, http1.Method("/{{$svrName}}/{{.Name}}"))
{{if .HasBody }}
path := binding.EncodeVars("{{.Path}}", in, {{.IsQuery}})
opts = append(opts, http.Operation("/{{$svrName}}/{{.Name}}"))
{{if .HasBody -}}
err := c.cc.Invoke(ctx, "{{.Method}}", path, in{{.Body}}, &out{{.ResponseBody}}, opts...)
{{else}}
{{else -}}
err := c.cc.Invoke(ctx, "{{.Method}}", path, nil, &out{{.ResponseBody}}, opts...)
{{end}}
{{end -}}
if err != nil {
return nil, err
}
return &out, err
}
{{end}}
@ -106,6 +101,7 @@ type methodDesc struct {
HasBody bool
Body string
ResponseBody string
IsQuery bool
}
func (s *serviceDesc) execute() string {
@ -121,5 +117,5 @@ func (s *serviceDesc) execute() string {
if err := tmpl.Execute(buf, s); err != nil {
panic(err)
}
return string(buf.Bytes())
return strings.Trim(string(buf.Bytes()), "\r\n")
}

@ -0,0 +1,6 @@
package main
const (
// Version is protoc-gen-go-http version
Version = "v2.0.0-rc3"
)

@ -0,0 +1,80 @@
package json
import (
"bytes"
"strings"
"testing"
)
type testEmbed struct {
Level1a int `json:"a"`
Level1b int `json:"b"`
Level1c int `json:"c"`
}
type testMessage struct {
Field1 string `json:"a"`
Field2 string `json:"b"`
Field3 string `json:"c"`
Embed *testEmbed `json:"embed,omitempty"`
}
func TestJSON_Marshal(t *testing.T) {
tests := []struct {
input interface{}
expect string
}{
{
input: &testMessage{},
expect: `{"a":"","b":"","c":""}`,
},
{
input: &testMessage{Field1: "a", Field2: "b", Field3: "c"},
expect: `{"a":"a","b":"b","c":"c"}`,
},
}
for _, v := range tests {
data, err := (codec{}).Marshal(v.input)
if err != nil {
t.Errorf("marshal(%#v): %s", v.input, err)
}
if got, want := string(data), v.expect; got != want {
if strings.Contains(want, "\n") {
t.Errorf("marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", v.input, got, want)
} else {
t.Errorf("marshal(%#v):\nhave %#q\nwant %#q", v.input, got, want)
}
}
}
}
func TestJSON_Unmarshal(t *testing.T) {
p := &testMessage{}
tests := []struct {
input string
expect interface{}
}{
{
input: `{"a":"","b":"","c":""}`,
expect: &testMessage{},
},
{
input: `{"a":"a","b":"b","c":"c"}`,
expect: &p,
},
}
for _, v := range tests {
want := []byte(v.input)
err := (codec{}).Unmarshal(want, &v.expect)
if err != nil {
t.Errorf("marshal(%#v): %s", v.input, err)
}
got, err := codec{}.Marshal(v.expect)
if err != nil {
t.Errorf("marshal(%#v): %s", v.input, err)
}
if !bytes.Equal(got, want) {
t.Errorf("marshal(%#v):\nhave %#q\nwant %#q", v.input, got, want)
}
}
}

@ -1,4 +1,6 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// protoc-gen-go-http v2.0.0-rc3
package v1
@ -6,256 +8,207 @@ import (
context "context"
middleware "github.com/go-kratos/kratos/v2/middleware"
transport "github.com/go-kratos/kratos/v2/transport"
http1 "github.com/go-kratos/kratos/v2/transport/http"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = new(middleware.Middleware)
var _ = new(transport.Transporter)
var _ = binding.BindVars
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
const _ = http.SupportPackageIsVersion1
type BlogServiceHandler interface {
type BlogServiceHTTPServer interface {
CreateArticle(context.Context, *CreateArticleRequest) (*CreateArticleReply, error)
DeleteArticle(context.Context, *DeleteArticleRequest) (*DeleteArticleReply, error)
GetArticle(context.Context, *GetArticleRequest) (*GetArticleReply, error)
ListArticle(context.Context, *ListArticleRequest) (*ListArticleReply, error)
UpdateArticle(context.Context, *UpdateArticleRequest) (*UpdateArticleReply, error)
}
func NewBlogServiceHandler(srv BlogServiceHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
func RegisterBlogServiceHTTPServer(s *http.Server, srv BlogServiceHTTPServer) {
r := s.Route("/")
r.POST("/v1/article/", _BlogService_CreateArticle0_HTTP_Handler(srv))
r.PUT("/v1/article/{id}", _BlogService_UpdateArticle0_HTTP_Handler(srv))
r.DELETE("/v1/article/{id}", _BlogService_DeleteArticle0_HTTP_Handler(srv))
r.GET("/v1/article/{id}", _BlogService_GetArticle0_HTTP_Handler(srv))
r.GET("/v1/article/", _BlogService_ListArticle0_HTTP_Handler(srv))
}
r.HandleFunc("/v1/article/", func(w http.ResponseWriter, r *http.Request) {
func _BlogService_CreateArticle0_HTTP_Handler(srv BlogServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in CreateArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/blog.api.v1.BlogService/CreateArticle")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.CreateArticle(ctx, req.(*CreateArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/blog.api.v1.BlogService/CreateArticle")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*CreateArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("POST")
return ctx.Result(200, reply)
}
}
r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
func _BlogService_UpdateArticle0_HTTP_Handler(srv BlogServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in UpdateArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/blog.api.v1.BlogService/UpdateArticle")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.UpdateArticle(ctx, req.(*UpdateArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/blog.api.v1.BlogService/UpdateArticle")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*UpdateArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("PUT")
return ctx.Result(200, reply)
}
}
r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
func _BlogService_DeleteArticle0_HTTP_Handler(srv BlogServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in DeleteArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/blog.api.v1.BlogService/DeleteArticle")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.DeleteArticle(ctx, req.(*DeleteArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/blog.api.v1.BlogService/DeleteArticle")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*DeleteArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("DELETE")
return ctx.Result(200, reply)
}
}
r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
func _BlogService_GetArticle0_HTTP_Handler(srv BlogServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in GetArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/blog.api.v1.BlogService/GetArticle")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetArticle(ctx, req.(*GetArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/blog.api.v1.BlogService/GetArticle")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*GetArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return ctx.Result(200, reply)
}
}
r.HandleFunc("/v1/article/", func(w http.ResponseWriter, r *http.Request) {
func _BlogService_ListArticle0_HTTP_Handler(srv BlogServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in ListArticleRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/blog.api.v1.BlogService/ListArticle")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.ListArticle(ctx, req.(*ListArticleRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/blog.api.v1.BlogService/ListArticle")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*ListArticleReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
return ctx.Result(200, reply)
}
}
type BlogServiceHTTPClient interface {
CreateArticle(ctx context.Context, req *CreateArticleRequest, opts ...http1.CallOption) (rsp *CreateArticleReply, err error)
DeleteArticle(ctx context.Context, req *DeleteArticleRequest, opts ...http1.CallOption) (rsp *DeleteArticleReply, err error)
GetArticle(ctx context.Context, req *GetArticleRequest, opts ...http1.CallOption) (rsp *GetArticleReply, err error)
ListArticle(ctx context.Context, req *ListArticleRequest, opts ...http1.CallOption) (rsp *ListArticleReply, err error)
UpdateArticle(ctx context.Context, req *UpdateArticleRequest, opts ...http1.CallOption) (rsp *UpdateArticleReply, err error)
CreateArticle(ctx context.Context, req *CreateArticleRequest, opts ...http.CallOption) (rsp *CreateArticleReply, err error)
DeleteArticle(ctx context.Context, req *DeleteArticleRequest, opts ...http.CallOption) (rsp *DeleteArticleReply, err error)
GetArticle(ctx context.Context, req *GetArticleRequest, opts ...http.CallOption) (rsp *GetArticleReply, err error)
ListArticle(ctx context.Context, req *ListArticleRequest, opts ...http.CallOption) (rsp *ListArticleReply, err error)
UpdateArticle(ctx context.Context, req *UpdateArticleRequest, opts ...http.CallOption) (rsp *UpdateArticleReply, err error)
}
type BlogServiceHTTPClientImpl struct {
cc *http1.Client
cc *http.Client
}
func NewBlogServiceHTTPClient(client *http1.Client) BlogServiceHTTPClient {
func NewBlogServiceHTTPClient(client *http.Client) BlogServiceHTTPClient {
return &BlogServiceHTTPClientImpl{client}
}
func (c *BlogServiceHTTPClientImpl) CreateArticle(ctx context.Context, in *CreateArticleRequest, opts ...http1.CallOption) (*CreateArticleReply, error) {
func (c *BlogServiceHTTPClientImpl) CreateArticle(ctx context.Context, in *CreateArticleRequest, opts ...http.CallOption) (*CreateArticleReply, error) {
var out CreateArticleReply
path := binding.EncodePath("POST", "/v1/article/", in)
opts = append(opts, http1.Method("/blog.api.v1.BlogService/CreateArticle"))
path := binding.EncodeVars("/v1/article/", in, false)
opts = append(opts, http.Operation("/blog.api.v1.BlogService/CreateArticle"))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *BlogServiceHTTPClientImpl) DeleteArticle(ctx context.Context, in *DeleteArticleRequest, opts ...http1.CallOption) (*DeleteArticleReply, error) {
func (c *BlogServiceHTTPClientImpl) DeleteArticle(ctx context.Context, in *DeleteArticleRequest, opts ...http.CallOption) (*DeleteArticleReply, error) {
var out DeleteArticleReply
path := binding.EncodePath("DELETE", "/v1/article/{id}", in)
opts = append(opts, http1.Method("/blog.api.v1.BlogService/DeleteArticle"))
path := binding.EncodeVars("/v1/article/{id}", in, false)
opts = append(opts, http.Operation("/blog.api.v1.BlogService/DeleteArticle"))
err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *BlogServiceHTTPClientImpl) GetArticle(ctx context.Context, in *GetArticleRequest, opts ...http1.CallOption) (*GetArticleReply, error) {
func (c *BlogServiceHTTPClientImpl) GetArticle(ctx context.Context, in *GetArticleRequest, opts ...http.CallOption) (*GetArticleReply, error) {
var out GetArticleReply
path := binding.EncodePath("GET", "/v1/article/{id}", in)
opts = append(opts, http1.Method("/blog.api.v1.BlogService/GetArticle"))
path := binding.EncodeVars("/v1/article/{id}", in, true)
opts = append(opts, http.Operation("/blog.api.v1.BlogService/GetArticle"))
err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *BlogServiceHTTPClientImpl) ListArticle(ctx context.Context, in *ListArticleRequest, opts ...http1.CallOption) (*ListArticleReply, error) {
func (c *BlogServiceHTTPClientImpl) ListArticle(ctx context.Context, in *ListArticleRequest, opts ...http.CallOption) (*ListArticleReply, error) {
var out ListArticleReply
path := binding.EncodePath("GET", "/v1/article/", in)
opts = append(opts, http1.Method("/blog.api.v1.BlogService/ListArticle"))
path := binding.EncodeVars("/v1/article/", in, true)
opts = append(opts, http.Operation("/blog.api.v1.BlogService/ListArticle"))
err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *BlogServiceHTTPClientImpl) UpdateArticle(ctx context.Context, in *UpdateArticleRequest, opts ...http1.CallOption) (*UpdateArticleReply, error) {
func (c *BlogServiceHTTPClientImpl) UpdateArticle(ctx context.Context, in *UpdateArticleRequest, opts ...http.CallOption) (*UpdateArticleReply, error) {
var out UpdateArticleReply
path := binding.EncodePath("PUT", "/v1/article/{id}", in)
opts = append(opts, http1.Method("/blog.api.v1.BlogService/UpdateArticle"))
path := binding.EncodeVars("/v1/article/{id}", in, false)
opts = append(opts, http.Operation("/blog.api.v1.BlogService/UpdateArticle"))
err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}

@ -1,134 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.7
// source: blog/api/blog/v1/error_reason.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ErrorReason int32
const (
ErrorReason_TITLE_MISSING ErrorReason = 0
ErrorReason_CONTENTMISSING ErrorReason = 1
)
// Enum value maps for ErrorReason.
var (
ErrorReason_name = map[int32]string{
0: "TITLE_MISSING",
1: "CONTENTMISSING",
}
ErrorReason_value = map[string]int32{
"TITLE_MISSING": 0,
"CONTENTMISSING": 1,
}
)
func (x ErrorReason) Enum() *ErrorReason {
p := new(ErrorReason)
*p = x
return p
}
func (x ErrorReason) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ErrorReason) Descriptor() protoreflect.EnumDescriptor {
return file_blog_api_blog_v1_error_reason_proto_enumTypes[0].Descriptor()
}
func (ErrorReason) Type() protoreflect.EnumType {
return &file_blog_api_blog_v1_error_reason_proto_enumTypes[0]
}
func (x ErrorReason) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ErrorReason.Descriptor instead.
func (ErrorReason) EnumDescriptor() ([]byte, []int) {
return file_blog_api_blog_v1_error_reason_proto_rawDescGZIP(), []int{0}
}
var File_blog_api_blog_v1_error_reason_proto protoreflect.FileDescriptor
var file_blog_api_blog_v1_error_reason_proto_rawDesc = []byte{
0x0a, 0x23, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f,
0x76, 0x31, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e,
0x76, 0x31, 0x2a, 0x34, 0x0a, 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f,
0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x49, 0x54, 0x4c, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49,
0x4e, 0x47, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, 0x4d,
0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x42, 0x57, 0x0a, 0x0e, 0x62, 0x6c, 0x6f, 0x67,
0x2e, 0x76, 0x31, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74,
0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x76,
0x31, 0xa2, 0x02, 0x0d, 0x41, 0x50, 0x49, 0x42, 0x6c, 0x6f, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72,
0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_blog_api_blog_v1_error_reason_proto_rawDescOnce sync.Once
file_blog_api_blog_v1_error_reason_proto_rawDescData = file_blog_api_blog_v1_error_reason_proto_rawDesc
)
func file_blog_api_blog_v1_error_reason_proto_rawDescGZIP() []byte {
file_blog_api_blog_v1_error_reason_proto_rawDescOnce.Do(func() {
file_blog_api_blog_v1_error_reason_proto_rawDescData = protoimpl.X.CompressGZIP(file_blog_api_blog_v1_error_reason_proto_rawDescData)
})
return file_blog_api_blog_v1_error_reason_proto_rawDescData
}
var file_blog_api_blog_v1_error_reason_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_blog_api_blog_v1_error_reason_proto_goTypes = []interface{}{
(ErrorReason)(0), // 0: api.blog.v1.ErrorReason
}
var file_blog_api_blog_v1_error_reason_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_blog_api_blog_v1_error_reason_proto_init() }
func file_blog_api_blog_v1_error_reason_proto_init() {
if File_blog_api_blog_v1_error_reason_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_blog_api_blog_v1_error_reason_proto_rawDesc,
NumEnums: 1,
NumMessages: 0,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_blog_api_blog_v1_error_reason_proto_goTypes,
DependencyIndexes: file_blog_api_blog_v1_error_reason_proto_depIdxs,
EnumInfos: file_blog_api_blog_v1_error_reason_proto_enumTypes,
}.Build()
File_blog_api_blog_v1_error_reason_proto = out.File
file_blog_api_blog_v1_error_reason_proto_rawDesc = nil
file_blog_api_blog_v1_error_reason_proto_goTypes = nil
file_blog_api_blog_v1_error_reason_proto_depIdxs = nil
}

@ -1,14 +0,0 @@
syntax = "proto3";
package api.blog.v1;
//
option go_package = "github.com/go-kratos/kratos/examples/blog/api/v1;v1";
option java_multiple_files = true;
option java_package = "blog.v1.errors";
option objc_class_prefix = "APIBlogErrors";
enum ErrorReason {
TITLE_MISSING = 0;
CONTENTMISSING = 1;
}

@ -6,7 +6,7 @@ import (
"os"
"time"
"github.com/go-kratos/kratos/examples/blog/api/blog/v1"
v1 "github.com/go-kratos/kratos/examples/blog/api/blog/v1"
"github.com/go-kratos/kratos/examples/blog/internal/conf"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/config"
@ -19,7 +19,6 @@ import (
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/semconv"
"gopkg.in/yaml.v2"
)
// go build -ldflags "-X main.Version=x.y.z"
@ -76,9 +75,6 @@ func main() {
config.WithSource(
file.NewSource(flagconf),
),
config.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {
return yaml.Unmarshal(kv.Value, v)
}),
)
if err := config.Load(); err != nil {
panic(err)

@ -27,8 +27,8 @@ func initApp(confServer *conf.Server, confData *conf.Data, traceTracerProvider t
articleRepo := data.NewArticleRepo(dataData, logger)
articleUsecase := biz.NewArticleUsecase(articleRepo, logger)
blogService := service.NewBlogService(articleUsecase, logger)
httpServer := server.NewHTTPServer(confServer, traceTracerProvider, blogService)
grpcServer := server.NewGRPCServer(confServer, traceTracerProvider, blogService)
httpServer := server.NewHTTPServer(confServer, logger, traceTracerProvider, blogService)
grpcServer := server.NewGRPCServer(confServer, logger, traceTracerProvider, blogService)
app := newApp(logger, httpServer, grpcServer)
return app, func() {
cleanup()

@ -14,12 +14,12 @@ import (
)
// NewGRPCServer new a gRPC server.
func NewGRPCServer(c *conf.Server, tracer trace.TracerProvider, blog *service.BlogService) *grpc.Server {
func NewGRPCServer(c *conf.Server, logger log.Logger, tracer trace.TracerProvider, blog *service.BlogService) *grpc.Server {
var opts = []grpc.ServerOption{
grpc.Middleware(
recovery.Recovery(),
tracing.Server(tracing.WithTracerProvider(tracer)),
logging.Server(log.DefaultLogger),
logging.Server(logger),
validate.Validator(),
),
}

@ -14,8 +14,15 @@ import (
)
// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, tracer trace.TracerProvider, blog *service.BlogService) *http.Server {
var opts []http.ServerOption
func NewHTTPServer(c *conf.Server, logger log.Logger, tracer trace.TracerProvider, blog *service.BlogService) *http.Server {
var opts = []http.ServerOption{
http.Middleware(
recovery.Recovery(),
tracing.Server(tracing.WithTracerProvider(tracer)),
logging.Server(logger),
validate.Validator(),
),
}
if c.Http.Network != "" {
opts = append(opts, http.Network(c.Http.Network))
}
@ -25,13 +32,7 @@ func NewHTTPServer(c *conf.Server, tracer trace.TracerProvider, blog *service.Bl
if c.Http.Timeout != nil {
opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
}
m := http.Middleware(
recovery.Recovery(),
tracing.Server(tracing.WithTracerProvider(tracer)),
logging.Server(log.DefaultLogger),
validate.Validator(),
)
srv := http.NewServer(opts...)
srv.HandlePrefix("/", v1.NewBlogServiceHandler(blog, m))
v1.RegisterBlogServiceHTTPServer(srv, blog)
return srv
}

@ -1,4 +1,6 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// protoc-gen-go-http v2.0.0-rc3
package helloworld
@ -6,86 +8,69 @@ import (
context "context"
middleware "github.com/go-kratos/kratos/v2/middleware"
transport "github.com/go-kratos/kratos/v2/transport"
http1 "github.com/go-kratos/kratos/v2/transport/http"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = new(middleware.Middleware)
var _ = new(transport.Transporter)
var _ = binding.BindVars
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
const _ = http.SupportPackageIsVersion1
type GreeterHandler interface {
type GreeterHTTPServer interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}
func NewGreeterHandler(srv GreeterHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
func RegisterGreeterHTTPServer(s *http.Server, srv GreeterHTTPServer) {
r := s.Route("/")
r.GET("/helloworld/{name}", _Greeter_SayHello0_HTTP_Handler(srv))
}
r.HandleFunc("/helloworld/{name}", func(w http.ResponseWriter, r *http.Request) {
func _Greeter_SayHello0_HTTP_Handler(srv GreeterHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in HelloRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/helloworld.Greeter/SayHello")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.SayHello(ctx, req.(*HelloRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/helloworld.Greeter/SayHello")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*HelloReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
return ctx.Result(200, reply)
}
}
type GreeterHTTPClient interface {
SayHello(ctx context.Context, req *HelloRequest, opts ...http1.CallOption) (rsp *HelloReply, err error)
SayHello(ctx context.Context, req *HelloRequest, opts ...http.CallOption) (rsp *HelloReply, err error)
}
type GreeterHTTPClientImpl struct {
cc *http1.Client
cc *http.Client
}
func NewGreeterHTTPClient(client *http1.Client) GreeterHTTPClient {
func NewGreeterHTTPClient(client *http.Client) GreeterHTTPClient {
return &GreeterHTTPClientImpl{client}
}
func (c *GreeterHTTPClientImpl) SayHello(ctx context.Context, in *HelloRequest, opts ...http1.CallOption) (*HelloReply, error) {
func (c *GreeterHTTPClientImpl) SayHello(ctx context.Context, in *HelloRequest, opts ...http.CallOption) (*HelloReply, error) {
var out HelloReply
path := binding.EncodePath("GET", "/helloworld/{name}", in)
opts = append(opts, http1.Method("/helloworld.Greeter/SayHello"))
path := binding.EncodeVars("/helloworld/{name}", in, true)
opts = append(opts, http.Operation("/helloworld.Greeter/SayHello"))
err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}

@ -42,25 +42,23 @@ func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloRe
func main() {
logger := log.NewStdLogger(os.Stdout)
log := log.NewHelper(logger)
s := &server{}
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
recovery.Recovery(),
logging.Server(logger),
))
s := &server{}
pb.RegisterGreeterServer(grpcSrv, s)
httpSrv := http.NewServer(http.Address(":8000"))
httpSrv.HandlePrefix("/", pb.NewGreeterHandler(s,
),
)
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
recovery.Recovery(),
logging.Server(logger),
)),
),
)
pb.RegisterGreeterServer(grpcSrv, s)
pb.RegisterGreeterHTTPServer(httpSrv, s)
app := kratos.New(
kratos.Name(Name),
@ -71,6 +69,6 @@ func main() {
)
if err := app.Run(); err != nil {
log.Error(err)
panic(err)
}
}

@ -1,52 +0,0 @@
package main
import (
"context"
"log"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/transport/http"
"github.com/gorilla/mux"
)
// User is a user model.
type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
// UserService is a user service.
type UserService struct{ users map[string]*User }
// Get get a user from memory.
func (u *UserService) Get(ctx context.Context, user *User) (*User, error) {
return u.users[user.ID], nil
}
// Add add a user to memory.
func (u *UserService) Add(ctx context.Context, user *User) (*User, error) {
u.users[user.ID] = user
return user, nil
}
func main() {
us := &UserService{
users: make(map[string]*User),
}
router := mux.NewRouter()
router.Handle("/users/add", http.NewHandler(us.Add)).Methods("POST")
router.Handle("/users/detail", http.NewHandler(us.Get)).Methods("GET")
httpSrv := http.NewServer(http.Address(":8000"))
httpSrv.HandlePrefix("/", router)
app := kratos.New(
kratos.Name("handler"),
kratos.Server(
httpSrv,
),
)
if err := app.Run(); err != nil {
log.Println(err)
}
}

@ -0,0 +1,28 @@
package main
import (
"context"
"github.com/go-kratos/kratos/examples/helloworld/helloworld"
"github.com/go-kratos/kratos/v2/transport"
"github.com/go-kratos/kratos/v2/transport/http"
"github.com/go-kratos/kratos/v2/transport/http/binding"
)
func sayHelloHandler(ctx http.Context) error {
var in helloworld.HelloRequest
if err := ctx.Bind(&in); err != nil {
return err
}
// binding /hello/{name} to in.Name
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
transport.SetOperation(ctx, "/helloworld.Greeter/SayHello")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return &helloworld.HelloReply{Message: "test:" + req.(*helloworld.HelloRequest).Name}, nil
})
return ctx.Returns(h(ctx, &in))
}

@ -0,0 +1,40 @@
package main
import (
"github.com/go-kratos/kratos/examples/helloworld/helloworld"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/transport/http"
)
// this example shows how to add middlewares,
// execution order is globalFilter(http) --> routeFilter(http) --> pathFilter(http) --> serviceFilter(service)
func main() {
s := &server{}
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
// add service filter
serviceMiddleware,
serviceMiddleware2,
),
// add global filter
http.Filter(globalFilter, globalFilter2),
)
// register http hanlder to http server
helloworld.RegisterGreeterHTTPServer(httpSrv, s)
// add route filter
r := httpSrv.Route("/", routeFilter, routeFilter2)
// add path filter to custom route
r.GET("/hello/{name}", sayHelloHandler, pathFilter, pathFilter2)
app := kratos.New(
kratos.Name("helloworld"),
kratos.Server(
httpSrv,
),
)
if err := app.Run(); err != nil {
panic(err)
}
}

@ -0,0 +1,75 @@
package main
import (
"context"
"fmt"
"net/http"
"github.com/go-kratos/kratos/v2/middleware"
)
func globalFilter(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("global filter in")
next.ServeHTTP(w, r)
fmt.Println("global filter out")
})
}
func globalFilter2(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("global filter 2 in")
next.ServeHTTP(w, r)
fmt.Println("global filter 2 out")
})
}
func routeFilter(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("route filter in")
next.ServeHTTP(w, r)
fmt.Println("route filter out")
})
}
func routeFilter2(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("route filter 2 in")
next.ServeHTTP(w, r)
fmt.Println("route filter 2 out")
})
}
func pathFilter(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("path filter in")
next.ServeHTTP(w, r)
fmt.Println("path filter out")
})
}
func pathFilter2(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("path filter 2 in")
next.ServeHTTP(w, r)
fmt.Println("path filter 2 out")
})
}
func serviceMiddleware(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
fmt.Println("service middleware in")
reply, err = handler(ctx, req)
fmt.Println("service middleware out")
return
}
}
func serviceMiddleware2(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
fmt.Println("service middleware 2 in")
reply, err = handler(ctx, req)
fmt.Println("service middleware 2 out")
return
}
}

@ -0,0 +1,25 @@
package main
import (
"context"
"fmt"
"github.com/go-kratos/kratos/examples/helloworld/helloworld"
"github.com/go-kratos/kratos/v2/errors"
)
// server is used to implement helloworld.GreeterServer.
type server struct {
helloworld.UnimplementedGreeterServer
}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
if in.Name == "error" {
return nil, errors.BadRequest("custom_error", fmt.Sprintf("invalid argument %s", in.Name))
}
if in.Name == "panic" {
panic("grpc panic")
}
return &helloworld.HelloReply{Message: fmt.Sprintf("Hello %+v", in.Name)}, nil
}

@ -1,42 +1,37 @@
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"github.com/go-kratos/kratos/v2"
transhttp "github.com/go-kratos/kratos/v2/transport/http"
"github.com/gorilla/mux"
"github.com/go-kratos/kratos/v2/transport/http"
)
func uploadFile(w http.ResponseWriter, r *http.Request) {
fileName := r.FormValue("name")
file, handler, err := r.FormFile("file")
func uploadFile(ctx http.Context) error {
req := ctx.Request()
fileName := req.FormValue("name")
file, handler, err := req.FormFile("file")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
return err
}
defer file.Close()
f, err := os.OpenFile(handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
return err
}
defer f.Close()
_, _ = io.Copy(f, file)
fmt.Fprint(w, "File "+fileName+" Uploaded successfully")
return ctx.String(200, "File "+fileName+" Uploaded successfully")
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/upload", uploadFile).Methods("POST")
httpSrv := transhttp.NewServer(transhttp.Address(":8000"))
httpSrv.HandlePrefix("/", router)
httpSrv := http.NewServer(http.Address(":8000"))
route := httpSrv.Route("/")
route.POST("/upload", uploadFile)
app := kratos.New(
kratos.Name("upload"),
@ -45,6 +40,6 @@ func main() {
),
)
if err := app.Run(); err != nil {
log.Println(err)
panic(err)
}
}

@ -39,25 +39,23 @@ func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloRe
func main() {
logger := log.NewStdLogger(os.Stdout)
log := log.NewHelper(logger)
s := &server{}
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
recovery.Recovery(),
logging.Server(logger),
))
s := &server{}
pb.RegisterGreeterServer(grpcSrv, s)
httpSrv := http.NewServer(http.Address(":8000"))
httpSrv.HandlePrefix("/", pb.NewGreeterHandler(s,
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
recovery.Recovery(),
logging.Server(logger),
)),
),
)
pb.RegisterGreeterServer(grpcSrv, s)
pb.RegisterGreeterHTTPServer(httpSrv, s)
app := kratos.New(
kratos.Name(Name),
@ -68,6 +66,6 @@ func main() {
)
if err := app.Run(); err != nil {
log.Error(err)
panic(err)
}
}

@ -1,380 +0,0 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
package testproto
import (
context "context"
middleware "github.com/go-kratos/kratos/v2/middleware"
transport "github.com/go-kratos/kratos/v2/transport"
http1 "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = new(middleware.Middleware)
var _ = new(transport.Transporter)
var _ = binding.BindVars
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
type EchoServiceHandler interface {
Echo(context.Context, *SimpleMessage) (*SimpleMessage, error)
EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error)
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 {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
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.BindVars(mux.Vars(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))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/Echo")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
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.BindVars(mux.Vars(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))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/Echo")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
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.BindVars(mux.Vars(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))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/Echo")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
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.BindVars(mux.Vars(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))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/Echo")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
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.BindVars(mux.Vars(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))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/Echo")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
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))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/EchoBody")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*SimpleMessage)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("POST")
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)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/EchoResponseBody")
out, err := next(ctx, &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.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoDelete(ctx, req.(*SimpleMessage))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/EchoDelete")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
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))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/testproto.EchoService/EchoPatch")
out, err := next(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
}
reply := out.(*DynamicMessageUpdate)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("PATCH")
return r
}
type EchoServiceHTTPClient interface {
Echo(ctx context.Context, req *SimpleMessage, opts ...http1.CallOption) (rsp *SimpleMessage, err error)
EchoBody(ctx context.Context, req *SimpleMessage, opts ...http1.CallOption) (rsp *SimpleMessage, err error)
EchoDelete(ctx context.Context, req *SimpleMessage, opts ...http1.CallOption) (rsp *SimpleMessage, err error)
EchoPatch(ctx context.Context, req *DynamicMessageUpdate, opts ...http1.CallOption) (rsp *DynamicMessageUpdate, err error)
EchoResponseBody(ctx context.Context, req *DynamicMessageUpdate, opts ...http1.CallOption) (rsp *DynamicMessageUpdate, err error)
}
type EchoServiceHTTPClientImpl struct {
cc *http1.Client
}
func NewEchoServiceHTTPClient(client *http1.Client) EchoServiceHTTPClient {
return &EchoServiceHTTPClientImpl{client}
}
func (c *EchoServiceHTTPClientImpl) Echo(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (*SimpleMessage, error) {
var out SimpleMessage
path := binding.EncodePath("POST", "/v1/example/echo/{id}", in)
opts = append(opts, http1.Method("/testproto.EchoService/Echo"))
err := c.cc.Invoke(ctx, "POST", path, nil, &out, opts...)
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoBody(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (*SimpleMessage, error) {
var out SimpleMessage
path := binding.EncodePath("POST", "/v1/example/echo_body", in)
opts = append(opts, http1.Method("/testproto.EchoService/EchoBody"))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (*SimpleMessage, error) {
var out SimpleMessage
path := binding.EncodePath("DELETE", "/v1/example/echo_delete/{id}/{num}", in)
opts = append(opts, http1.Method("/testproto.EchoService/EchoDelete"))
err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...)
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoPatch(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (*DynamicMessageUpdate, error) {
var out DynamicMessageUpdate
path := binding.EncodePath("PATCH", "/v1/example/echo_patch", in)
opts = append(opts, http1.Method("/testproto.EchoService/EchoPatch"))
err := c.cc.Invoke(ctx, "PATCH", path, in.Body, &out, opts...)
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (*DynamicMessageUpdate, error) {
var out DynamicMessageUpdate
path := binding.EncodePath("POST", "/v1/example/echo_response_body", in)
opts = append(opts, http1.Method("/testproto.EchoService/EchoResponseBody"))
err := c.cc.Invoke(ctx, "POST", path, in, &out.Body, opts...)
return &out, err
}

@ -1,86 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.7
// source: proto/stream.proto
package testproto
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
reflect "reflect"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
var File_proto_stream_proto protoreflect.FileDescriptor
var file_proto_stream_proto_rawDesc = []byte{
0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x62, 0x6f,
0x64, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x69, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x08, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f,
0x61, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x42, 0x6f, 0x64, 0x79,
0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78,
0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x30, 0x01,
0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67,
0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f,
0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67,
0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_proto_stream_proto_goTypes = []interface{}{
(*emptypb.Empty)(nil), // 0: google.protobuf.Empty
(*httpbody.HttpBody)(nil), // 1: google.api.HttpBody
}
var file_proto_stream_proto_depIdxs = []int32{
0, // 0: testproto.StreamService.Download:input_type -> google.protobuf.Empty
1, // 1: testproto.StreamService.Download:output_type -> google.api.HttpBody
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_proto_stream_proto_init() }
func file_proto_stream_proto_init() {
if File_proto_stream_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_stream_proto_rawDesc,
NumEnums: 0,
NumMessages: 0,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_stream_proto_goTypes,
DependencyIndexes: file_proto_stream_proto_depIdxs,
}.Build()
File_proto_stream_proto = out.File
file_proto_stream_proto_rawDesc = nil
file_proto_stream_proto_goTypes = nil
file_proto_stream_proto_depIdxs = nil
}

@ -28,12 +28,14 @@ func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloRe
func main() {
logger := log.NewStdLogger(os.Stdout)
log := log.NewHelper(logger)
consulClient, err := api.NewClient(api.DefaultConfig())
if err != nil {
panic(err)
}
r := registry.New(consulClient)
s := &server{}
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
@ -41,17 +43,15 @@ func main() {
logging.Server(logger),
),
)
s := &server{}
pb.RegisterGreeterServer(grpcSrv, s)
httpSrv := http.NewServer(http.Address(":8000"))
httpSrv.HandlePrefix("/", pb.NewGreeterHandler(s,
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
recovery.Recovery(),
)),
),
)
pb.RegisterGreeterServer(grpcSrv, s)
pb.RegisterGreeterHTTPServer(httpSrv, s)
r := registry.New(consulClient)
app := kratos.New(
kratos.Name("helloworld"),
kratos.Server(
@ -62,6 +62,6 @@ func main() {
)
if err := app.Run(); err != nil {
log.Errorf("app run failed:%v", err)
panic(err)
}
}

@ -1,4 +1,6 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// protoc-gen-go-http v2.0.0-rc3
package v1
@ -6,86 +8,69 @@ import (
context "context"
middleware "github.com/go-kratos/kratos/v2/middleware"
transport "github.com/go-kratos/kratos/v2/transport"
http1 "github.com/go-kratos/kratos/v2/transport/http"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = new(middleware.Middleware)
var _ = new(transport.Transporter)
var _ = binding.BindVars
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
const _ = http.SupportPackageIsVersion1
type MessageServiceHandler interface {
type MessageServiceHTTPServer interface {
GetUserMessage(context.Context, *GetUserMessageRequest) (*GetUserMessageReply, error)
}
func NewMessageServiceHandler(srv MessageServiceHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
func RegisterMessageServiceHTTPServer(s *http.Server, srv MessageServiceHTTPServer) {
r := s.Route("/")
r.GET("/v1/message/user/{id}/{count}", _MessageService_GetUserMessage0_HTTP_Handler(srv))
}
r.HandleFunc("/v1/message/user/{id}/{count}", func(w http.ResponseWriter, r *http.Request) {
func _MessageService_GetUserMessage0_HTTP_Handler(srv MessageServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in GetUserMessageRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/api.message.v1.MessageService/GetUserMessage")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetUserMessage(ctx, req.(*GetUserMessageRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/api.message.v1.MessageService/GetUserMessage")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*GetUserMessageReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
return ctx.Result(200, reply)
}
}
type MessageServiceHTTPClient interface {
GetUserMessage(ctx context.Context, req *GetUserMessageRequest, opts ...http1.CallOption) (rsp *GetUserMessageReply, err error)
GetUserMessage(ctx context.Context, req *GetUserMessageRequest, opts ...http.CallOption) (rsp *GetUserMessageReply, err error)
}
type MessageServiceHTTPClientImpl struct {
cc *http1.Client
cc *http.Client
}
func NewMessageServiceHTTPClient(client *http1.Client) MessageServiceHTTPClient {
func NewMessageServiceHTTPClient(client *http.Client) MessageServiceHTTPClient {
return &MessageServiceHTTPClientImpl{client}
}
func (c *MessageServiceHTTPClientImpl) GetUserMessage(ctx context.Context, in *GetUserMessageRequest, opts ...http1.CallOption) (*GetUserMessageReply, error) {
func (c *MessageServiceHTTPClientImpl) GetUserMessage(ctx context.Context, in *GetUserMessageRequest, opts ...http.CallOption) (*GetUserMessageReply, error) {
var out GetUserMessageReply
path := binding.EncodePath("GET", "/v1/message/user/{id}/{count}", in)
opts = append(opts, http1.Method("/api.message.v1.MessageService/GetUserMessage"))
path := binding.EncodeVars("/v1/message/user/{id}/{count}", in, true)
opts = append(opts, http.Operation("/api.message.v1.MessageService/GetUserMessage"))
err := c.cc.Invoke(ctx, "GET", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}

@ -1,4 +1,6 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// protoc-gen-go-http v2.0.0-rc3
package v1
@ -6,86 +8,69 @@ import (
context "context"
middleware "github.com/go-kratos/kratos/v2/middleware"
transport "github.com/go-kratos/kratos/v2/transport"
http1 "github.com/go-kratos/kratos/v2/transport/http"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
mux "github.com/gorilla/mux"
http "net/http"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(http.Request)
var _ = new(context.Context)
var _ = new(middleware.Middleware)
var _ = new(transport.Transporter)
var _ = binding.BindVars
var _ = mux.NewRouter
const _ = http1.SupportPackageIsVersion1
const _ = http.SupportPackageIsVersion1
type UserHandler interface {
type UserHTTPServer interface {
GetMyMessages(context.Context, *GetMyMessagesRequest) (*GetMyMessagesReply, error)
}
func NewUserHandler(srv UserHandler, opts ...http1.HandleOption) http.Handler {
h := http1.DefaultHandleOptions()
for _, o := range opts {
o(&h)
}
r := mux.NewRouter()
func RegisterUserHTTPServer(s *http.Server, srv UserHTTPServer) {
r := s.Route("/")
r.GET("/v1/user/get/message/{count}", _User_GetMyMessages0_HTTP_Handler(srv))
}
r.HandleFunc("/v1/user/get/message/{count}", func(w http.ResponseWriter, r *http.Request) {
func _User_GetMyMessages0_HTTP_Handler(srv UserHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in GetMyMessagesRequest
if err := h.Decode(r, &in); err != nil {
h.Error(w, r, err)
return
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(mux.Vars(r), &in); err != nil {
h.Error(w, r, err)
return
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
next := func(ctx context.Context, req interface{}) (interface{}, error) {
transport.SetOperation(ctx, "/api.user.v1.User/GetMyMessages")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetMyMessages(ctx, req.(*GetMyMessagesRequest))
}
if h.Middleware != nil {
next = h.Middleware(next)
}
ctx := r.Context()
transport.SetMethod(ctx, "/api.user.v1.User/GetMyMessages")
out, err := next(ctx, &in)
})
out, err := h(ctx, &in)
if err != nil {
h.Error(w, r, err)
return
return err
}
reply := out.(*GetMyMessagesReply)
if err := h.Encode(w, r, reply); err != nil {
h.Error(w, r, err)
}
}).Methods("GET")
return r
return ctx.Result(200, reply)
}
}
type UserHTTPClient interface {
GetMyMessages(ctx context.Context, req *GetMyMessagesRequest, opts ...http1.CallOption) (rsp *GetMyMessagesReply, err error)
GetMyMessages(ctx context.Context, req *GetMyMessagesRequest, opts ...http.CallOption) (rsp *GetMyMessagesReply, err error)
}
type UserHTTPClientImpl struct {
cc *http1.Client
cc *http.Client
}
func NewUserHTTPClient(client *http1.Client) UserHTTPClient {
func NewUserHTTPClient(client *http.Client) UserHTTPClient {
return &UserHTTPClientImpl{client}
}
func (c *UserHTTPClientImpl) GetMyMessages(ctx context.Context, in *GetMyMessagesRequest, opts ...http1.CallOption) (*GetMyMessagesReply, error) {
func (c *UserHTTPClientImpl) GetMyMessages(ctx context.Context, in *GetMyMessagesRequest, opts ...http.CallOption) (*GetMyMessagesReply, error) {
var out GetMyMessagesReply
path := binding.EncodePath("GET", "/v1/user/get/message/{count}", in)
opts = append(opts, http1.Method("/api.user.v1.User/GetMyMessages"))
path := binding.EncodeVars("/v1/user/get/message/{count}", in, true)
opts = append(opts, http.Operation("/api.user.v1.User/GetMyMessages"))
err := c.cc.Invoke(ctx, "GET", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}

@ -9,7 +9,6 @@ import (
pb "github.com/go-kratos/kratos/examples/traces/api/user"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/middleware/logging"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/tracing"
@ -63,14 +62,15 @@ func (s *server) GetMyMessages(ctx context.Context, in *pb.GetMyMessagesRequest)
// create grpc conn
conn, err := grpc.DialInsecure(ctx,
grpc.WithEndpoint("127.0.0.1:9000"),
grpc.WithMiddleware(middleware.Chain(
grpc.WithMiddleware(
recovery.Recovery(),
tracing.Client(
tracing.WithTracerProvider(s.tracer),
tracing.WithPropagators(
propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{}),
),
),
recovery.Recovery())),
),
grpc.WithTimeout(2*time.Second),
)
if err != nil {
@ -100,24 +100,22 @@ func main() {
log.Error(err)
}
s := &server{tracer: tp}
httpSrv := http.NewServer(http.Address(":8000"))
httpSrv.HandlePrefix("/", pb.NewUserHandler(s,
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
middleware.Chain(
recovery.Recovery(),
// Configuring tracing middleware
tracing.Server(
tracing.WithTracerProvider(tp),
tracing.WithPropagators(
propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{}),
),
recovery.Recovery(),
// Configuring tracing middleware
tracing.Server(
tracing.WithTracerProvider(tp),
tracing.WithPropagators(
propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{}),
),
logging.Server(logger),
),
)),
logging.Server(logger),
),
)
s := &server{tracer: tp}
pb.RegisterUserHTTPServer(httpSrv, s)
app := kratos.New(
kratos.Name(Name),

@ -2,7 +2,7 @@
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.7
// source: proto/echo_service.proto
// source: echo_service.proto
package testproto
@ -68,11 +68,11 @@ func (x Corpus) String() string {
}
func (Corpus) Descriptor() protoreflect.EnumDescriptor {
return file_proto_echo_service_proto_enumTypes[0].Descriptor()
return file_echo_service_proto_enumTypes[0].Descriptor()
}
func (Corpus) Type() protoreflect.EnumType {
return &file_proto_echo_service_proto_enumTypes[0]
return &file_echo_service_proto_enumTypes[0]
}
func (x Corpus) Number() protoreflect.EnumNumber {
@ -81,7 +81,7 @@ func (x Corpus) Number() protoreflect.EnumNumber {
// Deprecated: Use Corpus.Descriptor instead.
func (Corpus) EnumDescriptor() ([]byte, []int) {
return file_proto_echo_service_proto_rawDescGZIP(), []int{0}
return file_echo_service_proto_rawDescGZIP(), []int{0}
}
// Embedded represents a message embedded in SimpleMessage.
@ -99,7 +99,7 @@ type Embedded struct {
func (x *Embedded) Reset() {
*x = Embedded{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_echo_service_proto_msgTypes[0]
mi := &file_echo_service_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -112,7 +112,7 @@ func (x *Embedded) String() string {
func (*Embedded) ProtoMessage() {}
func (x *Embedded) ProtoReflect() protoreflect.Message {
mi := &file_proto_echo_service_proto_msgTypes[0]
mi := &file_echo_service_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -125,7 +125,7 @@ func (x *Embedded) ProtoReflect() protoreflect.Message {
// Deprecated: Use Embedded.ProtoReflect.Descriptor instead.
func (*Embedded) Descriptor() ([]byte, []int) {
return file_proto_echo_service_proto_rawDescGZIP(), []int{0}
return file_echo_service_proto_rawDescGZIP(), []int{0}
}
func (m *Embedded) GetMark() isEmbedded_Mark {
@ -189,7 +189,7 @@ type SimpleMessage struct {
func (x *SimpleMessage) Reset() {
*x = SimpleMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_echo_service_proto_msgTypes[1]
mi := &file_echo_service_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -202,7 +202,7 @@ func (x *SimpleMessage) String() string {
func (*SimpleMessage) ProtoMessage() {}
func (x *SimpleMessage) ProtoReflect() protoreflect.Message {
mi := &file_proto_echo_service_proto_msgTypes[1]
mi := &file_echo_service_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -215,7 +215,7 @@ func (x *SimpleMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use SimpleMessage.ProtoReflect.Descriptor instead.
func (*SimpleMessage) Descriptor() ([]byte, []int) {
return file_proto_echo_service_proto_rawDescGZIP(), []int{1}
return file_echo_service_proto_rawDescGZIP(), []int{1}
}
func (x *SimpleMessage) GetId() string {
@ -334,7 +334,7 @@ type DynamicMessage struct {
func (x *DynamicMessage) Reset() {
*x = DynamicMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_echo_service_proto_msgTypes[2]
mi := &file_echo_service_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -347,7 +347,7 @@ func (x *DynamicMessage) String() string {
func (*DynamicMessage) ProtoMessage() {}
func (x *DynamicMessage) ProtoReflect() protoreflect.Message {
mi := &file_proto_echo_service_proto_msgTypes[2]
mi := &file_echo_service_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -360,7 +360,7 @@ func (x *DynamicMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use DynamicMessage.ProtoReflect.Descriptor instead.
func (*DynamicMessage) Descriptor() ([]byte, []int) {
return file_proto_echo_service_proto_rawDescGZIP(), []int{2}
return file_echo_service_proto_rawDescGZIP(), []int{2}
}
func (x *DynamicMessage) GetStructField() *structpb.Struct {
@ -389,7 +389,7 @@ type DynamicMessageUpdate struct {
func (x *DynamicMessageUpdate) Reset() {
*x = DynamicMessageUpdate{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_echo_service_proto_msgTypes[3]
mi := &file_echo_service_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -402,7 +402,7 @@ func (x *DynamicMessageUpdate) String() string {
func (*DynamicMessageUpdate) ProtoMessage() {}
func (x *DynamicMessageUpdate) ProtoReflect() protoreflect.Message {
mi := &file_proto_echo_service_proto_msgTypes[3]
mi := &file_echo_service_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -415,7 +415,7 @@ func (x *DynamicMessageUpdate) ProtoReflect() protoreflect.Message {
// Deprecated: Use DynamicMessageUpdate.ProtoReflect.Descriptor instead.
func (*DynamicMessageUpdate) Descriptor() ([]byte, []int) {
return file_proto_echo_service_proto_rawDescGZIP(), []int{3}
return file_echo_service_proto_rawDescGZIP(), []int{3}
}
func (x *DynamicMessageUpdate) GetBody() *DynamicMessage {
@ -432,129 +432,129 @@ func (x *DynamicMessageUpdate) GetUpdateMask() *fieldmaskpb.FieldMask {
return nil
}
var File_proto_echo_service_proto protoreflect.FileDescriptor
var file_proto_echo_service_proto_rawDesc = []byte{
0x0a, 0x18, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x73, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x65, 0x73, 0x74,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a, 0x08, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12,
0x1c, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x48, 0x00, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a,
0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e,
0x6f, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x22, 0x84, 0x02, 0x0a, 0x0d,
0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a,
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a,
0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12,
0x1b, 0x0a, 0x08, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28,
0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x14, 0x0a, 0x04,
0x6c, 0x61, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6c, 0x61,
0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45,
0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x10, 0x0a, 0x02, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x02, 0x65,
0x6e, 0x12, 0x25, 0x0a, 0x02, 0x6e, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64,
0x65, 0x64, 0x48, 0x01, 0x52, 0x02, 0x6e, 0x6f, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x72, 0x70,
0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x72,
0x70, 0x75, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x65,
0x78, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x0e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f,
0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c,
0x64, 0x12, 0x37, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x82, 0x01, 0x0a, 0x14, 0x44,
0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x19, 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, 0x52, 0x04, 0x62, 0x6f,
0x64, 0x79, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73,
0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d,
0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x2a,
0x5a, 0x0a, 0x06, 0x43, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x49,
0x56, 0x45, 0x52, 0x53, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x57, 0x45, 0x42, 0x10,
0x01, 0x12, 0x0a, 0x0a, 0x06, 0x49, 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, 0xcf, 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,
var File_echo_service_proto protoreflect.FileDescriptor
var file_echo_service_proto_rawDesc = []byte{
0x0a, 0x12, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66,
0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a,
0x08, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x70, 0x72, 0x6f,
0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x70,
0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x42, 0x06, 0x0a,
0x04, 0x6d, 0x61, 0x72, 0x6b, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02,
0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x69, 0x6e,
0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c,
0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x06,
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74,
0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65,
0x64, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x02, 0x65, 0x6e, 0x18,
0x06, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x02, 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x02, 0x6e,
0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x48, 0x01, 0x52, 0x02,
0x6e, 0x6f, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43,
0x6f, 0x72, 0x70, 0x75, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x42, 0x06, 0x0a,
0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x65, 0x78, 0x74, 0x22, 0x85, 0x01, 0x0a,
0x0e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
0x3a, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b,
0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x37, 0x0a, 0x0b, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46,
0x69, 0x65, 0x6c, 0x64, 0x22, 0x82, 0x01, 0x0a, 0x14, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a,
0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 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, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x3b, 0x0a, 0x0b,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x2a, 0x5a, 0x0a, 0x06, 0x43, 0x6f, 0x72,
0x70, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x49, 0x56, 0x45, 0x52, 0x53, 0x41, 0x4c,
0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x57, 0x45, 0x42, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x49,
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, 0xcf, 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, 0x22, 0xb5, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0xae, 0x01, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31,
0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69,
0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x5a, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x2f,
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64,
0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x6c, 0x61, 0x6e, 0x67, 0x7d, 0x5a, 0x31,
0x12, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63,
0x68, 0x6f, 0x31, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e,
0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x6e, 0x6f, 0x74, 0x65,
0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x2f, 0x65, 0x63, 0x68, 0x6f, 0x32, 0x2f, 0x7b, 0x6e, 0x6f, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x7d,
0x12, 0x60, 0x0a, 0x08, 0x45, 0x63, 0x68, 0x6f, 0x42, 0x6f, 0x64, 0x79, 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, 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, 0x85, 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, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x29, 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, 0x3a, 0x01, 0x2a, 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,
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, 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, 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, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32,
0x16, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68,
0x6f, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x51, 0x5a,
0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b,
0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68,
0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73,
0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x67, 0x65, 0x22, 0xb5, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0xae, 0x01, 0x22, 0x15, 0x2f, 0x76,
0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b,
0x69, 0x64, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75,
0x6d, 0x7d, 0x5a, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d,
0x7d, 0x2f, 0x7b, 0x6c, 0x61, 0x6e, 0x67, 0x7d, 0x5a, 0x31, 0x12, 0x2f, 0x2f, 0x76, 0x31, 0x2f,
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x31, 0x2f, 0x7b, 0x69,
0x64, 0x7d, 0x2f, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f,
0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x32,
0x2f, 0x7b, 0x6e, 0x6f, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x7d, 0x12, 0x60, 0x0a, 0x08, 0x45, 0x63,
0x68, 0x6f, 0x42, 0x6f, 0x64, 0x79, 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, 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, 0x85, 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, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 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, 0x3a, 0x01, 0x2a, 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, 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, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x65,
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x63,
0x68, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f,
0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
file_proto_echo_service_proto_rawDescOnce sync.Once
file_proto_echo_service_proto_rawDescData = file_proto_echo_service_proto_rawDesc
file_echo_service_proto_rawDescOnce sync.Once
file_echo_service_proto_rawDescData = file_echo_service_proto_rawDesc
)
func file_proto_echo_service_proto_rawDescGZIP() []byte {
file_proto_echo_service_proto_rawDescOnce.Do(func() {
file_proto_echo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_echo_service_proto_rawDescData)
func file_echo_service_proto_rawDescGZIP() []byte {
file_echo_service_proto_rawDescOnce.Do(func() {
file_echo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_echo_service_proto_rawDescData)
})
return file_proto_echo_service_proto_rawDescData
return file_echo_service_proto_rawDescData
}
var file_proto_echo_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_proto_echo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_proto_echo_service_proto_goTypes = []interface{}{
var file_echo_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_echo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_echo_service_proto_goTypes = []interface{}{
(Corpus)(0), // 0: testproto.Corpus
(*Embedded)(nil), // 1: testproto.Embedded
(*SimpleMessage)(nil), // 2: testproto.SimpleMessage
@ -564,7 +564,7 @@ var file_proto_echo_service_proto_goTypes = []interface{}{
(*structpb.Value)(nil), // 6: google.protobuf.Value
(*fieldmaskpb.FieldMask)(nil), // 7: google.protobuf.FieldMask
}
var file_proto_echo_service_proto_depIdxs = []int32{
var file_echo_service_proto_depIdxs = []int32{
1, // 0: testproto.SimpleMessage.status:type_name -> testproto.Embedded
1, // 1: testproto.SimpleMessage.no:type_name -> testproto.Embedded
0, // 2: testproto.SimpleMessage.corpus:type_name -> testproto.Corpus
@ -589,13 +589,13 @@ var file_proto_echo_service_proto_depIdxs = []int32{
0, // [0:7] is the sub-list for field type_name
}
func init() { file_proto_echo_service_proto_init() }
func file_proto_echo_service_proto_init() {
if File_proto_echo_service_proto != nil {
func init() { file_echo_service_proto_init() }
func file_echo_service_proto_init() {
if File_echo_service_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_echo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
file_echo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Embedded); i {
case 0:
return &v.state
@ -607,7 +607,7 @@ func file_proto_echo_service_proto_init() {
return nil
}
}
file_proto_echo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
file_echo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SimpleMessage); i {
case 0:
return &v.state
@ -619,7 +619,7 @@ func file_proto_echo_service_proto_init() {
return nil
}
}
file_proto_echo_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
file_echo_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DynamicMessage); i {
case 0:
return &v.state
@ -631,7 +631,7 @@ func file_proto_echo_service_proto_init() {
return nil
}
}
file_proto_echo_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
file_echo_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DynamicMessageUpdate); i {
case 0:
return &v.state
@ -644,11 +644,11 @@ func file_proto_echo_service_proto_init() {
}
}
}
file_proto_echo_service_proto_msgTypes[0].OneofWrappers = []interface{}{
file_echo_service_proto_msgTypes[0].OneofWrappers = []interface{}{
(*Embedded_Progress)(nil),
(*Embedded_Note)(nil),
}
file_proto_echo_service_proto_msgTypes[1].OneofWrappers = []interface{}{
file_echo_service_proto_msgTypes[1].OneofWrappers = []interface{}{
(*SimpleMessage_LineNum)(nil),
(*SimpleMessage_Lang)(nil),
(*SimpleMessage_En)(nil),
@ -658,19 +658,19 @@ func file_proto_echo_service_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_echo_service_proto_rawDesc,
RawDescriptor: file_echo_service_proto_rawDesc,
NumEnums: 1,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_echo_service_proto_goTypes,
DependencyIndexes: file_proto_echo_service_proto_depIdxs,
EnumInfos: file_proto_echo_service_proto_enumTypes,
MessageInfos: file_proto_echo_service_proto_msgTypes,
GoTypes: file_echo_service_proto_goTypes,
DependencyIndexes: file_echo_service_proto_depIdxs,
EnumInfos: file_echo_service_proto_enumTypes,
MessageInfos: file_echo_service_proto_msgTypes,
}.Build()
File_proto_echo_service_proto = out.File
file_proto_echo_service_proto_rawDesc = nil
file_proto_echo_service_proto_goTypes = nil
file_proto_echo_service_proto_depIdxs = nil
File_echo_service_proto = out.File
file_echo_service_proto_rawDesc = nil
file_echo_service_proto_goTypes = nil
file_echo_service_proto_depIdxs = nil
}

@ -257,5 +257,5 @@ var EchoService_ServiceDesc = grpc.ServiceDesc{
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/echo_service.proto",
Metadata: "echo_service.proto",
}

@ -0,0 +1,303 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// protoc-gen-go-http v2.0.0-rc3
package testproto
import (
context "context"
middleware "github.com/go-kratos/kratos/v2/middleware"
transport "github.com/go-kratos/kratos/v2/transport"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(context.Context)
var _ = new(middleware.Middleware)
var _ = new(transport.Transporter)
var _ = binding.BindVars
const _ = http.SupportPackageIsVersion1
type EchoServiceHTTPServer interface {
Echo(context.Context, *SimpleMessage) (*SimpleMessage, error)
EchoBody(context.Context, *SimpleMessage) (*SimpleMessage, error)
EchoDelete(context.Context, *SimpleMessage) (*SimpleMessage, error)
EchoPatch(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error)
EchoResponseBody(context.Context, *DynamicMessageUpdate) (*DynamicMessageUpdate, error)
}
func RegisterEchoServiceHTTPServer(s *http.Server, srv EchoServiceHTTPServer) {
r := s.Route("/")
r.GET("/v1/example/echo/{id}/{num}", _EchoService_Echo0_HTTP_Handler(srv))
r.GET("/v1/example/echo/{id}/{num}/{lang}", _EchoService_Echo1_HTTP_Handler(srv))
r.GET("/v1/example/echo1/{id}/{line_num}/{status.note}", _EchoService_Echo2_HTTP_Handler(srv))
r.GET("/v1/example/echo2/{no.note}", _EchoService_Echo3_HTTP_Handler(srv))
r.POST("/v1/example/echo/{id}", _EchoService_Echo4_HTTP_Handler(srv))
r.POST("/v1/example/echo_body", _EchoService_EchoBody0_HTTP_Handler(srv))
r.POST("/v1/example/echo_response_body", _EchoService_EchoResponseBody0_HTTP_Handler(srv))
r.DELETE("/v1/example/echo_delete/{id}/{num}", _EchoService_EchoDelete0_HTTP_Handler(srv))
r.PATCH("/v1/example/echo_patch", _EchoService_EchoPatch0_HTTP_Handler(srv))
}
func _EchoService_Echo0_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SimpleMessage
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/Echo")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SimpleMessage)
return ctx.Result(200, reply)
}
}
func _EchoService_Echo1_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SimpleMessage
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/Echo")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SimpleMessage)
return ctx.Result(200, reply)
}
}
func _EchoService_Echo2_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SimpleMessage
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/Echo")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SimpleMessage)
return ctx.Result(200, reply)
}
}
func _EchoService_Echo3_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SimpleMessage
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/Echo")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SimpleMessage)
return ctx.Result(200, reply)
}
}
func _EchoService_Echo4_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SimpleMessage
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/Echo")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Echo(ctx, req.(*SimpleMessage))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SimpleMessage)
return ctx.Result(200, reply)
}
}
func _EchoService_EchoBody0_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SimpleMessage
if err := ctx.Bind(&in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/EchoBody")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoBody(ctx, req.(*SimpleMessage))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SimpleMessage)
return ctx.Result(200, reply)
}
}
func _EchoService_EchoResponseBody0_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in DynamicMessageUpdate
if err := ctx.Bind(&in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/EchoResponseBody")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoResponseBody(ctx, req.(*DynamicMessageUpdate))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*DynamicMessageUpdate)
return ctx.Result(200, reply.Body)
}
}
func _EchoService_EchoDelete0_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SimpleMessage
if err := ctx.Bind(&in); err != nil {
return err
}
if err := binding.BindVars(ctx.Vars(), &in); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/EchoDelete")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoDelete(ctx, req.(*SimpleMessage))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SimpleMessage)
return ctx.Result(200, reply)
}
}
func _EchoService_EchoPatch0_HTTP_Handler(srv EchoServiceHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in DynamicMessageUpdate
if err := ctx.Bind(&in.Body); err != nil {
return err
}
transport.SetOperation(ctx, "/testproto.EchoService/EchoPatch")
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.EchoPatch(ctx, req.(*DynamicMessageUpdate))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*DynamicMessageUpdate)
return ctx.Result(200, reply)
}
}
type EchoServiceHTTPClient interface {
Echo(ctx context.Context, req *SimpleMessage, opts ...http.CallOption) (rsp *SimpleMessage, err error)
EchoBody(ctx context.Context, req *SimpleMessage, opts ...http.CallOption) (rsp *SimpleMessage, err error)
EchoDelete(ctx context.Context, req *SimpleMessage, opts ...http.CallOption) (rsp *SimpleMessage, err error)
EchoPatch(ctx context.Context, req *DynamicMessageUpdate, opts ...http.CallOption) (rsp *DynamicMessageUpdate, err error)
EchoResponseBody(ctx context.Context, req *DynamicMessageUpdate, opts ...http.CallOption) (rsp *DynamicMessageUpdate, err error)
}
type EchoServiceHTTPClientImpl struct {
cc *http.Client
}
func NewEchoServiceHTTPClient(client *http.Client) EchoServiceHTTPClient {
return &EchoServiceHTTPClientImpl{client}
}
func (c *EchoServiceHTTPClientImpl) Echo(ctx context.Context, in *SimpleMessage, opts ...http.CallOption) (*SimpleMessage, error) {
var out SimpleMessage
path := binding.EncodeVars("/v1/example/echo/{id}", in, false)
opts = append(opts, http.Operation("/testproto.EchoService/Echo"))
err := c.cc.Invoke(ctx, "POST", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoBody(ctx context.Context, in *SimpleMessage, opts ...http.CallOption) (*SimpleMessage, error) {
var out SimpleMessage
path := binding.EncodeVars("/v1/example/echo_body", in, false)
opts = append(opts, http.Operation("/testproto.EchoService/EchoBody"))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...http.CallOption) (*SimpleMessage, error) {
var out SimpleMessage
path := binding.EncodeVars("/v1/example/echo_delete/{id}/{num}", in, false)
opts = append(opts, http.Operation("/testproto.EchoService/EchoDelete"))
err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoPatch(ctx context.Context, in *DynamicMessageUpdate, opts ...http.CallOption) (*DynamicMessageUpdate, error) {
var out DynamicMessageUpdate
path := binding.EncodeVars("/v1/example/echo_patch", in, false)
opts = append(opts, http.Operation("/testproto.EchoService/EchoPatch"))
err := c.cc.Invoke(ctx, "PATCH", path, in.Body, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EchoServiceHTTPClientImpl) EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate, opts ...http.CallOption) (*DynamicMessageUpdate, error) {
var out DynamicMessageUpdate
path := binding.EncodeVars("/v1/example/echo_response_body", in, false)
opts = append(opts, http.Operation("/testproto.EchoService/EchoResponseBody"))
err := c.cc.Invoke(ctx, "POST", path, in, &out.Body, opts...)
if err != nil {
return nil, err
}
return &out, err
}

@ -2,21 +2,32 @@ package testproto
import (
context "context"
"errors"
"fmt"
"net"
http "net/http"
"testing"
"time"
"github.com/go-kratos/kratos/v2/encoding"
tr "github.com/go-kratos/kratos/v2/transport/http"
"github.com/go-kratos/kratos/v2/metadata"
"github.com/go-kratos/kratos/v2/transport"
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-kratos/kratos/v2/transport/http"
_struct "github.com/golang/protobuf/ptypes/struct"
grpcmd "google.golang.org/grpc/metadata"
)
var md = metadata.Metadata{"test_key": "test_value"}
type echoService struct {
UnimplementedEchoServiceServer
}
func (s *echoService) Echo(ctx context.Context, m *SimpleMessage) (*SimpleMessage, error) {
md := transport.Metadata(ctx)
if v := md.Get("test_key"); v != "test_value" {
return nil, errors.New("md not match" + v)
}
return m, nil
}
@ -42,7 +53,7 @@ type echoClient struct {
// post: /v1/example/echo/{id}
func (c *echoClient) Echo(ctx context.Context, in *SimpleMessage) (out *SimpleMessage, err error) {
return c.client.Echo(ctx, in)
return c.client.Echo(ctx, in, http.Metadata(md))
}
// post: /v1/example/echo_body
@ -65,25 +76,47 @@ func (c *echoClient) EchoResponseBody(ctx context.Context, in *DynamicMessageUpd
return c.client.EchoResponseBody(ctx, in)
}
func TestEchoService(t *testing.T) {
s := &echoService{}
h := NewEchoServiceHandler(s)
srv := &http.Server{Addr: ":0", Handler: h}
lis, err := net.Listen("tcp", srv.Addr)
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)
}
addr := lis.Addr().(*net.TCPAddr)
time.AfterFunc(time.Second, func() {
defer srv.Shutdown(context.Background())
testEchoClient(t, fmt.Sprintf("127.0.0.1:%d", addr.Port))
})
if err := srv.Serve(lis); err != nil && err != http.ErrServerClosed {
if err := codec.Unmarshal(data, out); err != nil {
t.Fatal(err)
}
// body
in2 := &DynamicMessageUpdate{Body: &DynamicMessage{
ValueField: &_struct.Value{Kind: &_struct.Value_StringValue{StringValue: "test"}},
}}
out2 := &DynamicMessageUpdate{}
data, err = codec.Marshal(&in2.Body)
if err != nil {
t.Fatal(err)
}
if err := codec.Unmarshal(data, &out2.Body); err != nil {
t.Fatal(err)
}
}
func testEchoClient(t *testing.T, addr string) {
func TestEchoHTTPServer(t *testing.T) {
echo := &echoService{}
ctx := context.Background()
srv := http.NewServer(http.Address(":2333"))
RegisterEchoServiceHTTPServer(srv, echo)
go func() {
if err := srv.Start(ctx); err != nil {
panic(err)
}
}()
time.Sleep(time.Second)
testEchoHTTPClient(t, fmt.Sprintf("127.0.0.1:2333"))
srv.Stop(ctx)
}
func testEchoHTTPClient(t *testing.T, addr string) {
var (
err error
in = &SimpleMessage{Id: "test_id", Num: 100}
@ -94,7 +127,7 @@ func testEchoClient(t *testing.T, addr string) {
t.Errorf("[%s] expected %v got %v", name, in, out)
}
}
cc, _ := tr.NewClient(context.Background(), tr.WithEndpoint(addr))
cc, _ := http.NewClient(context.Background(), http.WithEndpoint(addr))
cli := &echoClient{client: NewEchoServiceHTTPClient(cc)}
@ -137,15 +170,37 @@ func testEchoClient(t *testing.T, addr string) {
fmt.Println("echo test success!")
}
func TestJSON(t *testing.T) {
in := &SimpleMessage{Id: "test_id", Num: 100}
out := &SimpleMessage{}
codec := encoding.GetCodec("json")
data, err := codec.Marshal(in)
func TestEchoGRPCServer(t *testing.T) {
echo := &echoService{}
ctx := context.Background()
srv := grpc.NewServer(grpc.Address(":2233"))
RegisterEchoServiceServer(srv, echo)
go func() {
if err := srv.Start(ctx); err != nil {
panic(err)
}
}()
time.Sleep(time.Second)
testEchoGRPCClient(t, fmt.Sprintf("127.0.0.1:2233"))
srv.Stop(ctx)
}
func testEchoGRPCClient(t *testing.T, addr string) {
ctx := context.Background()
cc, err := grpc.DialInsecure(ctx, grpc.WithEndpoint(addr))
if err != nil {
t.Fatal(err)
}
if err := codec.Unmarshal(data, out); err != nil {
var (
in = &SimpleMessage{Id: "test_id", Num: 100}
out = &SimpleMessage{}
)
client := NewEchoServiceClient(cc)
ctx = grpcmd.NewOutgoingContext(ctx, grpcmd.New(md))
if out, err = client.Echo(ctx, in); err != nil {
t.Fatal(err)
}
if in.Id != out.Id || in.Num != out.Num {
t.Errorf("expected %v got %v", in, out)
}
}

@ -0,0 +1,3 @@
package testproto
//go:generate protoc --proto_path=. --proto_path=../../third_party --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. --go-http_out=paths=source_relative:. echo_service.proto stream.proto

@ -0,0 +1,86 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.7
// source: stream.proto
package testproto
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb"
reflect "reflect"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
var File_stream_proto protoreflect.FileDescriptor
var file_stream_proto_rawDesc = []byte{
0x0a, 0x0c, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09,
0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32,
0x69, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x58, 0x0a, 0x08, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x30, 0x01, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74,
0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70,
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_stream_proto_goTypes = []interface{}{
(*emptypb.Empty)(nil), // 0: google.protobuf.Empty
(*httpbody.HttpBody)(nil), // 1: google.api.HttpBody
}
var file_stream_proto_depIdxs = []int32{
0, // 0: testproto.StreamService.Download:input_type -> google.protobuf.Empty
1, // 1: testproto.StreamService.Download:output_type -> google.api.HttpBody
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_stream_proto_init() }
func file_stream_proto_init() {
if File_stream_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_stream_proto_rawDesc,
NumEnums: 0,
NumMessages: 0,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_stream_proto_goTypes,
DependencyIndexes: file_stream_proto_depIdxs,
}.Build()
File_stream_proto = out.File
file_stream_proto_rawDesc = nil
file_stream_proto_goTypes = nil
file_stream_proto_depIdxs = nil
}

@ -126,5 +126,5 @@ var StreamService_ServiceDesc = grpc.ServiceDesc{
ServerStreams: true,
},
},
Metadata: "proto/stream.proto",
Metadata: "stream.proto",
}

@ -16,15 +16,15 @@ func Server(logger log.Logger) middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
var (
code int32
reason string
kind string
method string
code int32
reason string
kind string
operation string
)
startTime := time.Now()
if info, ok := transport.FromServerContext(ctx); ok {
kind = info.Kind()
method = info.Method()
operation = info.Operation()
}
reply, err = handler(ctx, req)
if se := errors.FromError(err); se != nil {
@ -35,7 +35,7 @@ func Server(logger log.Logger) middleware.Middleware {
log.WithContext(ctx, logger).Log(level,
"kind", "server",
"component", kind,
"method", method,
"operation", operation,
"args", extractArgs(req),
"code", code,
"reason", reason,
@ -52,15 +52,15 @@ func Client(logger log.Logger) middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
var (
code int32
reason string
kind string
method string
code int32
reason string
kind string
operation string
)
startTime := time.Now()
if info, ok := transport.FromClientContext(ctx); ok {
kind = info.Kind()
method = info.Method()
operation = info.Operation()
}
reply, err = handler(ctx, req)
if se := errors.FromError(err); se != nil {
@ -71,7 +71,7 @@ func Client(logger log.Logger) middleware.Middleware {
log.WithContext(ctx, logger).Log(level,
"kind", "client",
"component", kind,
"method", method,
"operation", operation,
"args", extractArgs(req),
"code", code,
"reason", reason,

@ -17,9 +17,9 @@ var (
)
type Transport struct {
kind string
endpoint string
method string
kind string
endpoint string
operation string
}
func (tr *Transport) Kind() string {
@ -30,12 +30,12 @@ func (tr *Transport) Endpoint() string {
return tr.endpoint
}
func (tr *Transport) Method() string {
return tr.method
func (tr *Transport) Operation() string {
return tr.operation
}
func (tr *Transport) SetMethod(method string) {
tr.method = method
func (tr *Transport) SetOperation(operation string) {
tr.operation = operation
}
func (tr *Transport) Metadata() metadata.Metadata {
@ -61,21 +61,21 @@ func TestHTTP(t *testing.T) {
Server,
err,
func() context.Context {
return transport.NewServerContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
return transport.NewServerContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", operation: "/package.service/method"})
}(),
},
{"http-server@succ",
Server,
nil,
func() context.Context {
return transport.NewServerContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
return transport.NewServerContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", operation: "/package.service/method"})
}(),
},
{"http-client@succ",
Client,
nil,
func() context.Context {
return transport.NewClientContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
return transport.NewClientContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", operation: "/package.service/method"})
}(),
},
@ -83,7 +83,7 @@ func TestHTTP(t *testing.T) {
Client,
err,
func() context.Context {
return transport.NewClientContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
return transport.NewClientContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", operation: "/package.service/method"})
}(),
},
}

@ -29,9 +29,9 @@ func WithSeconds(c metrics.Observer) Option {
}
type options struct {
// counter: <client/server>_requests_code_total{kind, method, code, reason}
// counter: <client/server>_requests_code_total{kind, operation, code, reason}
requests metrics.Counter
// histogram: <client/server>_requests_seconds_bucket{kind, method}
// histogram: <client/server>_requests_seconds_bucket{kind, operation}
seconds metrics.Observer
}
@ -44,15 +44,15 @@ func Server(opts ...Option) middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (interface{}, error) {
var (
code int
reason string
kind string
method string
code int
reason string
kind string
operation string
)
startTime := time.Now()
if info, ok := transport.FromServerContext(ctx); ok {
kind = info.Kind()
method = info.Method()
operation = info.Operation()
}
reply, err := handler(ctx, req)
if se := errors.FromError(err); se != nil {
@ -60,10 +60,10 @@ func Server(opts ...Option) middleware.Middleware {
reason = se.Reason
}
if options.requests != nil {
options.requests.With(kind, method, strconv.Itoa(code), reason).Inc()
options.requests.With(kind, operation, strconv.Itoa(code), reason).Inc()
}
if options.seconds != nil {
options.seconds.With(kind, method).Observe(time.Since(startTime).Seconds())
options.seconds.With(kind, operation).Observe(time.Since(startTime).Seconds())
}
return reply, err
}
@ -79,15 +79,15 @@ func Client(opts ...Option) middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{}) (interface{}, error) {
var (
code int
reason string
kind string
method string
code int
reason string
kind string
operation string
)
startTime := time.Now()
if info, ok := transport.FromClientContext(ctx); ok {
kind = info.Kind()
method = info.Method()
operation = info.Operation()
}
reply, err := handler(ctx, req)
if se := errors.FromError(err); se != nil {
@ -95,10 +95,10 @@ func Client(opts ...Option) middleware.Middleware {
reason = se.Reason
}
if options.requests != nil {
options.requests.With(kind, method, strconv.Itoa(code), reason).Inc()
options.requests.With(kind, operation, strconv.Itoa(code), reason).Inc()
}
if options.seconds != nil {
options.seconds.With(kind, method).Observe(time.Since(startTime).Seconds())
options.seconds.With(kind, operation).Observe(time.Since(startTime).Seconds())
}
return reply, err
}

@ -38,7 +38,7 @@ func Server(opts ...Option) middleware.Middleware {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
if tr, ok := transport.FromServerContext(ctx); ok {
var span trace.Span
ctx, span = tracer.Start(ctx, tr.Kind(), tr.Method(), tr.Metadata())
ctx, span = tracer.Start(ctx, tr.Kind(), tr.Operation(), tr.Metadata())
defer func() { tracer.End(ctx, span, err) }()
}
return handler(ctx, req)
@ -53,7 +53,7 @@ func Client(opts ...Option) middleware.Middleware {
return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
if tr, ok := transport.FromClientContext(ctx); ok {
var span trace.Span
ctx, span = tracer.Start(ctx, tr.Kind(), tr.Method(), tr.Metadata())
ctx, span = tracer.Start(ctx, tr.Kind(), tr.Operation(), tr.Metadata())
defer func() { tracer.End(ctx, span, err) }()
}
return handler(ctx, req)

@ -38,7 +38,7 @@ func WithTimeout(timeout time.Duration) ClientOption {
// WithMiddleware with client middleware.
func WithMiddleware(m ...middleware.Middleware) ClientOption {
return func(o *clientOptions) {
o.middleware = middleware.Chain(m...)
o.middleware = m
}
}
@ -67,8 +67,8 @@ func WithOptions(opts ...grpc.DialOption) ClientOption {
type clientOptions struct {
endpoint string
timeout time.Duration
middleware middleware.Middleware
discovery registry.Discovery
middleware []middleware.Middleware
ints []grpc.UnaryClientInterceptor
grpcOpts []grpc.DialOption
}
@ -112,12 +112,12 @@ func dial(ctx context.Context, insecure bool, opts ...ClientOption) (*grpc.Clien
return grpc.DialContext(ctx, options.endpoint, grpcOpts...)
}
func unaryClientInterceptor(m middleware.Middleware, timeout time.Duration) grpc.UnaryClientInterceptor {
func unaryClientInterceptor(ms []middleware.Middleware, timeout time.Duration) grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
ctx = transport.NewClientContext(ctx, &Transport{
endpoint: cc.Target(),
method: method,
metadata: metadata.Metadata{},
endpoint: cc.Target(),
operation: method,
metadata: metadata.Metadata{},
})
if timeout > 0 {
var cancel context.CancelFunc
@ -130,8 +130,8 @@ func unaryClientInterceptor(m middleware.Middleware, timeout time.Duration) grpc
}
return reply, invoker(ctx, method, req, reply, cc, opts...)
}
if m != nil {
h = m(h)
if len(ms) > 0 {
h = middleware.Chain(ms...)(h)
}
_, err := h(ctx, req)
return err

@ -59,7 +59,7 @@ func Logger(logger log.Logger) ServerOption {
// Middleware with server middleware.
func Middleware(m ...middleware.Middleware) ServerOption {
return func(s *Server) {
s.middleware = middleware.Chain(m...)
s.middleware = m
}
}
@ -89,7 +89,7 @@ type Server struct {
endpoint *url.URL
timeout time.Duration
log *log.Helper
middleware middleware.Middleware
middleware []middleware.Middleware
ints []grpc.UnaryServerInterceptor
grpcOpts []grpc.ServerOption
health *health.Server
@ -179,9 +179,9 @@ func (s *Server) unaryServerInterceptor() grpc.UnaryServerInterceptor {
defer cancel()
md, _ := grpcmd.FromIncomingContext(ctx)
ctx = transport.NewServerContext(ctx, &Transport{
endpoint: s.endpoint.String(),
method: info.FullMethod,
metadata: metadata.New(md),
endpoint: s.endpoint.String(),
operation: info.FullMethod,
metadata: metadata.New(md),
})
if s.timeout > 0 {
var cancel context.CancelFunc
@ -191,8 +191,8 @@ func (s *Server) unaryServerInterceptor() grpc.UnaryServerInterceptor {
h := func(ctx context.Context, req interface{}) (interface{}, error) {
return handler(ctx, req)
}
if s.middleware != nil {
h = s.middleware(h)
if len(s.middleware) > 0 {
h = middleware.Chain(s.middleware...)(h)
}
return h(ctx, req)
}

@ -11,9 +11,9 @@ var (
// Transport is a gRPC transport.
type Transport struct {
endpoint string
method string
metadata metadata.Metadata
endpoint string
operation string
metadata metadata.Metadata
}
// Kind returns the transport kind.
@ -26,14 +26,14 @@ func (tr *Transport) Endpoint() string {
return tr.endpoint
}
// Method returns the transport method.
func (tr *Transport) Method() string {
return tr.method
// Operation returns the transport operation.
func (tr *Transport) Operation() string {
return tr.operation
}
// SetMethod sets the transport method.
func (tr *Transport) SetMethod(method string) {
tr.method = method
// SetOperation sets the transport operation.
func (tr *Transport) SetOperation(operation string) {
tr.operation = operation
}
// Metadata returns the transport metadata.
@ -43,10 +43,6 @@ func (tr *Transport) Metadata() metadata.Metadata {
// WithMetadata with a metadata into transport md.
func (tr *Transport) WithMetadata(md metadata.Metadata) {
if tr.metadata == nil {
tr.metadata = md
return
}
for k, v := range md {
tr.metadata.Set(k, v)
}

@ -18,11 +18,7 @@ func BindForm(req *http.Request, target interface{}) error {
}
// BindVars bind map parameters to target.
func BindVars(vars map[string]string, target interface{}) error {
values := make(map[string][]string, len(vars))
for k, v := range vars {
values[k] = []string{v}
}
func BindVars(values map[string][]string, target interface{}) error {
if msg, ok := target.(proto.Message); ok {
return mapProto(msg, values)
}

@ -18,8 +18,8 @@ import (
"google.golang.org/protobuf/types/known/wrapperspb"
)
// EncodePath binds proto message to url path
func EncodePath(method string, pathPattern string, msg proto.Message) string {
// EncodeVars binds proto message to url path
func EncodeVars(pathPattern string, msg proto.Message, isQuery bool) string {
if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
return pathPattern
}
@ -40,7 +40,7 @@ func EncodePath(method string, pathPattern string, msg proto.Message) string {
}
return in
})
if method == "GET" {
if isQuery {
u, err := encodeQuery(msg)
if err == nil && len(u) > 0 {
for key := range pathParams {

@ -6,25 +6,25 @@ import (
)
func TestProtoPath(t *testing.T) {
url := EncodePath("POST", "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}})
url := EncodeVars("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}}, false)
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/test/sub/2233!!!` {
t.Fatalf("proto path not expected!actual: %s ", url)
}
url = EncodePath("POST", "http://helloworld.Greeter/helloworld/sub", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}})
url = EncodeVars("http://helloworld.Greeter/helloworld/sub", &HelloRequest{Name: "test", Sub: &Sub{Name: "2233!!!"}}, false)
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/sub` {
t.Fatalf("proto path not expected!actual: %s ", url)
}
url = EncodePath("POST", "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test"})
url = EncodeVars("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &HelloRequest{Name: "test"}, false)
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/test/sub/` {
t.Fatalf("proto path not expected!actual: %s ", url)
}
url = EncodePath("POST", "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name33}", &HelloRequest{Name: "test"})
url = EncodeVars("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name33}", &HelloRequest{Name: "test"}, false)
fmt.Println(url)
if url != `http://helloworld.Greeter/helloworld/test/sub/{sub.name33}` {
t.Fatalf("proto path not expected!actual: %s ", url)

@ -16,7 +16,7 @@ type CallOption interface {
type callInfo struct {
contentType string
method string
operation string
metatada metadata.Metadata
}
@ -49,24 +49,24 @@ func (o ContentTypeCallOption) before(c *callInfo) error {
func defaultCallInfo(path string) callInfo {
return callInfo{
contentType: "application/json",
method: path,
operation: path,
metatada: metadata.Metadata{},
}
}
// Method is serviceMethod call option
func Method(method string) CallOption {
return MethodCallOption{Method: method}
// Operation is serviceMethod call option
func Operation(operation string) CallOption {
return OperationCallOption{Operation: operation}
}
// MethodCallOption is set ServiceMethod for client call
type MethodCallOption struct {
// OperationCallOption is set ServiceMethod for client call
type OperationCallOption struct {
EmptyCallOption
Method string
Operation string
}
func (o MethodCallOption) before(c *callInfo) error {
c.method = o.Method
func (o OperationCallOption) before(c *callInfo) error {
c.operation = o.Operation
return nil
}

@ -44,7 +44,7 @@ type clientOptions struct {
transport http.RoundTripper
balancer balancer.Balancer
discovery registry.Discovery
middleware middleware.Middleware
middleware []middleware.Middleware
}
// WithTransport with client transport.
@ -71,7 +71,7 @@ func WithUserAgent(ua string) ClientOption {
// WithMiddleware with client middleware.
func WithMiddleware(m ...middleware.Middleware) ClientOption {
return func(o *clientOptions) {
o.middleware = middleware.Chain(m...)
o.middleware = m
}
}
@ -201,9 +201,11 @@ func (client *Client) Invoke(ctx context.Context, method, path string, args inte
c.metatada = metadata.Metadata{}
}
ctx = transport.NewClientContext(ctx, &Transport{
endpoint: client.opts.endpoint,
metadata: c.metatada,
method: c.method,
endpoint: client.opts.endpoint,
metadata: c.metatada,
path: path,
method: method,
operation: c.operation,
})
return client.invoke(ctx, req, args, reply, c)
}
@ -246,8 +248,8 @@ func (client *Client) invoke(ctx context.Context, req *http.Request, args interf
}
return reply, nil
}
if client.opts.middleware != nil {
h = client.opts.middleware(h)
if len(client.opts.middleware) > 0 {
h = middleware.Chain(client.opts.middleware...)(h)
}
_, err := h(ctx, args)
return err

@ -0,0 +1,89 @@
package http
import (
"io/ioutil"
"net/http"
"github.com/go-kratos/kratos/v2/encoding"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/internal/httputil"
"github.com/go-kratos/kratos/v2/transport/http/binding"
)
// SupportPackageIsVersion1 These constants should not be referenced from any other code.
const SupportPackageIsVersion1 = true
// DecodeRequestFunc is decode request func.
type DecodeRequestFunc func(*http.Request, interface{}) error
// EncodeResponseFunc is encode response func.
type EncodeResponseFunc func(http.ResponseWriter, *http.Request, interface{}) error
// EncodeErrorFunc is encode error func.
type EncodeErrorFunc func(http.ResponseWriter, *http.Request, error)
// DefaultRequestDecoder decodes the request body to object.
func DefaultRequestDecoder(r *http.Request, v interface{}) error {
codec, ok := CodecForRequest(r, "Content-Type")
if ok {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
return errors.BadRequest("CODEC", err.Error())
}
if err := codec.Unmarshal(data, v); err != nil {
return errors.BadRequest("CODEC", err.Error())
}
} else {
if err := binding.BindForm(r, v); err != nil {
return errors.BadRequest("CODEC", err.Error())
}
}
return nil
}
// DefaultResponseEncoder encodes the object to the HTTP response.
func DefaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{}) error {
codec, _ := CodecForRequest(r, "Accept")
data, err := codec.Marshal(v)
if err != nil {
return err
}
w.Header().Set("Content-Type", httputil.ContentType(codec.Name()))
if sc, ok := v.(interface {
StatusCode() int
}); ok {
w.WriteHeader(sc.StatusCode())
}
_, _ = w.Write(data)
return nil
}
// DefaultErrorEncoder encodes the error to the HTTP response.
func DefaultErrorEncoder(w http.ResponseWriter, r *http.Request, se error) {
codec, _ := CodecForRequest(r, "Accept")
body, err := codec.Marshal(se)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", httputil.ContentType(codec.Name()))
if sc, ok := se.(interface {
StatusCode() int
}); ok {
w.WriteHeader(sc.StatusCode())
} else {
w.WriteHeader(http.StatusInternalServerError)
}
w.Write(body)
}
// CodecForRequest get encoding.Codec via http.Request
func CodecForRequest(r *http.Request, name string) (encoding.Codec, bool) {
for _, accept := range r.Header[name] {
codec := encoding.GetCodec(httputil.ContentSubtype(accept))
if codec != nil {
return codec, true
}
}
return encoding.GetCodec("json"), false
}

@ -0,0 +1,142 @@
package http
import (
"context"
"encoding/json"
"encoding/xml"
"io"
"net/http"
"net/url"
"time"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/gorilla/mux"
)
var _ Context = (*wrapper)(nil)
// HandlerFunc defines a function to serve HTTP requests.
type HandlerFunc func(Context) error
// Context is an HTTP Context.
type Context interface {
context.Context
Vars() url.Values
Form() url.Values
Header() http.Header
Request() *http.Request
Response() http.ResponseWriter
Middleware(middleware.Handler) middleware.Handler
Bind(interface{}) error
Returns(interface{}, error) error
Result(int, interface{}) error
JSON(int, interface{}) error
XML(int, interface{}) error
String(int, string) error
Blob(int, string, []byte) error
Stream(int, string, io.Reader) error
Reset(http.ResponseWriter, *http.Request)
}
type wrapper struct {
route *Route
req *http.Request
res http.ResponseWriter
}
func (c *wrapper) Header() http.Header {
return c.req.Header
}
func (c *wrapper) Vars() url.Values {
raws := mux.Vars(c.req)
vars := make(url.Values, len(raws))
for k, v := range raws {
vars[k] = []string{v}
}
return vars
}
func (c *wrapper) Form() url.Values {
if err := c.req.ParseForm(); err != nil {
return url.Values{}
}
return c.req.Form
}
func (c *wrapper) Request() *http.Request { return c.req }
func (c *wrapper) Response() http.ResponseWriter { return c.res }
func (c *wrapper) Middleware(h middleware.Handler) middleware.Handler {
return middleware.Chain(c.route.srv.ms...)(h)
}
func (c *wrapper) Bind(v interface{}) error { return c.route.srv.dec(c.req, v) }
func (c *wrapper) Returns(v interface{}, err error) error {
if err != nil {
return err
}
if err := c.route.srv.enc(c.res, c.req, v); err != nil {
return err
}
return nil
}
func (c *wrapper) Result(code int, v interface{}) error {
c.res.WriteHeader(code)
if err := c.route.srv.enc(c.res, c.req, v); err != nil {
return err
}
return nil
}
func (c *wrapper) JSON(code int, v interface{}) error {
c.res.WriteHeader(code)
c.res.Header().Set("Content-Type", "application/json")
return json.NewEncoder(c.res).Encode(v)
}
func (c *wrapper) XML(code int, v interface{}) error {
c.res.WriteHeader(code)
c.res.Header().Set("Content-Type", "application/xml")
return xml.NewEncoder(c.res).Encode(v)
}
func (c *wrapper) String(code int, text string) error {
c.res.WriteHeader(code)
c.res.Header().Set("Content-Type", "text/plain")
c.res.Write([]byte(text))
return nil
}
func (c *wrapper) Blob(code int, contentType string, data []byte) error {
c.res.WriteHeader(code)
c.res.Header().Set("Content-Type", contentType)
c.res.Write(data)
return nil
}
func (c *wrapper) Stream(code int, contentType string, rd io.Reader) error {
c.res.WriteHeader(code)
c.res.Header().Set("Content-Type", contentType)
_, err := io.Copy(c.res, rd)
return err
}
func (c *wrapper) Reset(res http.ResponseWriter, req *http.Request) {
c.res = res
c.req = req
}
func (c *wrapper) Deadline() (time.Time, bool) {
if c.req == nil {
return time.Time{}, false
}
return c.req.Context().Deadline()
}
func (c *wrapper) Done() <-chan struct{} {
if c.req == nil {
return nil
}
return c.req.Context().Done()
}
func (c *wrapper) Err() error {
if c.req == nil {
return context.Canceled
}
return c.req.Context().Err()
}
func (c *wrapper) Value(key interface{}) interface{} {
if c.req == nil {
return nil
}
return c.req.Context().Value(key)
}

@ -1,215 +0,0 @@
package http
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"reflect"
"github.com/go-kratos/kratos/v2/encoding"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/internal/httputil"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport/http/binding"
)
// SupportPackageIsVersion1 These constants should not be referenced from any other code.
const SupportPackageIsVersion1 = true
// DecodeRequestFunc is decode request func.
type DecodeRequestFunc func(*http.Request, interface{}) error
// EncodeResponseFunc is encode response func.
type EncodeResponseFunc func(http.ResponseWriter, *http.Request, interface{}) error
// EncodeErrorFunc is encode error func.
type EncodeErrorFunc func(http.ResponseWriter, *http.Request, error)
// HandleOption is handle option.
type HandleOption func(*HandleOptions)
// HandleOptions is handle options.
// Deprecated: use Handler instead.
type HandleOptions struct {
Decode DecodeRequestFunc
Encode EncodeResponseFunc
Error EncodeErrorFunc
Middleware middleware.Middleware
}
// DefaultHandleOptions returns a default handle options.
// Deprecated: use NewHandler instead.
func DefaultHandleOptions() HandleOptions {
return HandleOptions{
Decode: DefaultRequestDecoder,
Encode: DefaultResponseEncoder,
Error: DefaultErrorEncoder,
}
}
// RequestDecoder with request decoder.
func RequestDecoder(dec DecodeRequestFunc) HandleOption {
return func(o *HandleOptions) {
o.Decode = dec
}
}
// ResponseEncoder with response encoder.
func ResponseEncoder(en EncodeResponseFunc) HandleOption {
return func(o *HandleOptions) {
o.Encode = en
}
}
// ErrorEncoder with error encoder.
func ErrorEncoder(en EncodeErrorFunc) HandleOption {
return func(o *HandleOptions) {
o.Error = en
}
}
// Middleware with middleware option.
func Middleware(m ...middleware.Middleware) HandleOption {
return func(o *HandleOptions) {
o.Middleware = middleware.Chain(m...)
}
}
// Handler is handle options.
type Handler struct {
method reflect.Value
in reflect.Type
out reflect.Type
opts HandleOptions
}
// NewHandler new an HTTP handler.
func NewHandler(handler interface{}, opts ...HandleOption) http.Handler {
if err := validateHandler(handler); err != nil {
panic(err)
}
typ := reflect.TypeOf(handler)
h := &Handler{
method: reflect.ValueOf(handler),
in: typ.In(1).Elem(),
out: typ.Out(0).Elem(),
opts: DefaultHandleOptions(),
}
for _, o := range opts {
o(&h.opts)
}
return h
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
in := reflect.New(h.in).Interface()
if err := h.opts.Decode(req, in); err != nil {
h.opts.Error(w, req, err)
return
}
invoke := func(ctx context.Context, in interface{}) (interface{}, error) {
ret := h.method.Call([]reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(in),
})
if ret[1].IsNil() {
return ret[0].Interface(), nil
}
return nil, ret[1].Interface().(error)
}
if h.opts.Middleware != nil {
invoke = h.opts.Middleware(invoke)
}
out, err := invoke(req.Context(), in)
if err != nil {
h.opts.Error(w, req, err)
return
}
if err := h.opts.Encode(w, req, out); err != nil {
h.opts.Error(w, req, err)
}
}
func validateHandler(handler interface{}) error {
typ := reflect.TypeOf(handler)
if typ.NumIn() != 2 || typ.NumOut() != 2 {
return fmt.Errorf("invalid types, in: %d out: %d", typ.NumIn(), typ.NumOut())
}
if typ.In(1).Kind() != reflect.Ptr || typ.Out(0).Kind() != reflect.Ptr {
return fmt.Errorf("invalid types is not a pointer")
}
if !typ.In(0).Implements(reflect.TypeOf((*context.Context)(nil)).Elem()) {
return fmt.Errorf("input does not implement the context")
}
if !typ.Out(1).Implements(reflect.TypeOf((*error)(nil)).Elem()) {
return fmt.Errorf("input does not implement the error")
}
return nil
}
// DefaultRequestDecoder decodes the request body to object.
func DefaultRequestDecoder(r *http.Request, v interface{}) error {
codec, ok := CodecForRequest(r, "Content-Type")
if ok {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
return errors.BadRequest("CODEC", err.Error())
}
if err := codec.Unmarshal(data, v); err != nil {
return errors.BadRequest("CODEC", err.Error())
}
} else {
if err := binding.BindForm(r, v); err != nil {
return errors.BadRequest("CODEC", err.Error())
}
}
return nil
}
// DefaultResponseEncoder encodes the object to the HTTP response.
func DefaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{}) error {
codec, _ := CodecForRequest(r, "Accept")
data, err := codec.Marshal(v)
if err != nil {
return err
}
w.Header().Set("Content-Type", httputil.ContentType(codec.Name()))
if sc, ok := v.(interface {
StatusCode() int
}); ok {
w.WriteHeader(sc.StatusCode())
}
_, _ = w.Write(data)
return nil
}
// DefaultErrorEncoder encodes the error to the HTTP response.
func DefaultErrorEncoder(w http.ResponseWriter, r *http.Request, se error) {
codec, _ := CodecForRequest(r, "Accept")
body, err := codec.Marshal(se)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", httputil.ContentType(codec.Name()))
if sc, ok := se.(interface {
StatusCode() int
}); ok {
w.WriteHeader(sc.StatusCode())
} else {
w.WriteHeader(http.StatusInternalServerError)
}
w.Write(body)
}
// CodecForRequest get encoding.Codec via http.Request
func CodecForRequest(r *http.Request, name string) (encoding.Codec, bool) {
for _, accept := range r.Header[name] {
codec := encoding.GetCodec(httputil.ContentSubtype(accept))
if codec != nil {
return codec, true
}
}
return encoding.GetCodec("json"), false
}

@ -1,24 +0,0 @@
package http
import (
"context"
"testing"
)
type HelloRequest struct {
Name string `json:"name"`
}
type HelloReply struct {
Message string `json:"message"`
}
type GreeterService struct {
}
func (s *GreeterService) SayHello(ctx context.Context, req *HelloRequest) (*HelloReply, error) {
return &HelloReply{Message: "hello " + req.Name}, nil
}
func TestHandler(t *testing.T) {
s := &GreeterService{}
_ = NewHandler(s.SayHello)
}

@ -0,0 +1,101 @@
package http
import (
"net/http"
"path"
"sync"
)
// FilterFunc is a function which receives an http.Handler and returns another http.Handler.
type FilterFunc func(http.Handler) http.Handler
// FilterChain returns a FilterFunc that specifies the chained handler for HTTP Router.
func FilterChain(filters ...FilterFunc) FilterFunc {
return func(next http.Handler) http.Handler {
for i := len(filters) - 1; i >= 0; i-- {
next = filters[i](next)
}
return next
}
}
// Route is an HTTP route.
type Route struct {
prefix string
pool sync.Pool
srv *Server
filters []FilterFunc
}
func newRoute(prefix string, srv *Server, filters ...FilterFunc) *Route {
r := &Route{
prefix: prefix,
srv: srv,
filters: filters,
}
r.pool.New = func() interface{} {
return &wrapper{route: r}
}
return r
}
// Handle registers a new route with a matcher for the URL path and method.
func (r *Route) Handle(method, relativePath string, h HandlerFunc, filters ...FilterFunc) {
next := http.Handler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
ctx := r.pool.Get().(Context)
ctx.Reset(res, req)
if err := h(ctx); err != nil {
r.srv.ene(res, req, err)
}
ctx.Reset(nil, nil)
r.pool.Put(ctx)
}))
next = FilterChain(filters...)(next)
next = FilterChain(r.filters...)(next)
r.srv.router.Handle(path.Join(r.prefix, relativePath), next).Methods(method)
}
// GET registers a new GET route for a path with matching handler in the router.
func (r *Route) GET(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodGet, path, h, m...)
}
// HEAD registers a new HEAD route for a path with matching handler in the router.
func (r *Route) HEAD(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodHead, path, h, m...)
}
// POST registers a new POST route for a path with matching handler in the router.
func (r *Route) POST(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodPost, path, h, m...)
}
// PUT registers a new PUT route for a path with matching handler in the router.
func (r *Route) PUT(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodPut, path, h, m...)
}
// PATCH registers a new PATCH route for a path with matching handler in the router.
func (r *Route) PATCH(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodPatch, path, h, m...)
}
// DELETE registers a new DELETE route for a path with matching handler in the router.
func (r *Route) DELETE(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodDelete, path, h, m...)
}
// CONNECT registers a new CONNECT route for a path with matching handler in the router.
func (r *Route) CONNECT(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodConnect, path, h, m...)
}
// OPTIONS registers a new OPTIONS route for a path with matching handler in the router.
func (r *Route) OPTIONS(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodOptions, path, h, m...)
}
// TRACE registers a new TRACE route for a path with matching handler in the router.
func (r *Route) TRACE(path string, h HandlerFunc, m ...FilterFunc) {
r.Handle(http.MethodTrace, path, h, m...)
}

@ -0,0 +1,135 @@
package http
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"testing"
"time"
"github.com/go-kratos/kratos/v2/internal/host"
)
type User struct {
Name string `json:"name"`
}
func authFilter(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Do stuff here
log.Println("auth:", r.Method, r.RequestURI)
// Call the next handler, which can be another middleware in the chain, or the final handler.
next.ServeHTTP(w, r)
})
}
func loggingFilter(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Do stuff here
log.Println("logging:", r.Method, r.RequestURI)
// Call the next handler, which can be another middleware in the chain, or the final handler.
next.ServeHTTP(w, r)
})
}
func TestRoute(t *testing.T) {
ctx := context.Background()
srv := NewServer(
Filter(loggingFilter),
)
route := srv.Route("/v1")
route.GET("/users/{name}", func(ctx Context) error {
u := new(User)
u.Name = ctx.Vars().Get("name")
return ctx.Result(200, u)
}, authFilter)
route.POST("/users", func(ctx Context) error {
u := new(User)
if err := ctx.Bind(u); err != nil {
return err
}
return ctx.Result(201, u)
})
route.PUT("/users", func(ctx Context) error {
u := new(User)
if err := ctx.Bind(u); err != nil {
return err
}
h := ctx.Middleware(func(ctx context.Context, in interface{}) (interface{}, error) {
return u, nil
})
return ctx.Returns(h(ctx, u))
})
if e, err := srv.Endpoint(); err != nil || e == nil {
t.Fatal(e, err)
}
go func() {
if err := srv.Start(ctx); err != nil {
panic(err)
}
}()
time.Sleep(time.Second)
testRoute(t, srv)
srv.Stop(ctx)
}
func testRoute(t *testing.T, srv *Server) {
port, ok := host.Port(srv.lis)
if !ok {
t.Fatalf("extract port error: %v", srv.lis)
}
base := fmt.Sprintf("http://127.0.0.1:%d/v1", port)
// GET
resp, err := http.Get(base + "/users/foo")
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
t.Fatalf("code: %d", resp.StatusCode)
}
u := new(User)
if err := json.NewDecoder(resp.Body).Decode(u); err != nil {
t.Fatal(err)
}
if u.Name != "foo" {
t.Fatalf("got %s want foo", u.Name)
}
// POST
resp, err = http.Post(base+"/users", "application/json", strings.NewReader(`{"name":"bar"}`))
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 201 {
t.Fatalf("code: %d", resp.StatusCode)
}
u = new(User)
if err = json.NewDecoder(resp.Body).Decode(u); err != nil {
t.Fatal(err)
}
if u.Name != "bar" {
t.Fatalf("got %s want bar", u.Name)
}
// PUT
req, _ := http.NewRequest("PUT", base+"/users", strings.NewReader(`{"name":"bar"}`))
req.Header.Set("Content-Type", "application/json")
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
t.Fatalf("code: %d", resp.StatusCode)
}
u = new(User)
if err = json.NewDecoder(resp.Body).Decode(u); err != nil {
t.Fatal(err)
}
if u.Name != "bar" {
t.Fatalf("got %s want bar", u.Name)
}
}

@ -13,6 +13,7 @@ import (
"github.com/go-kratos/kratos/v2/internal/host"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/metadata"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport"
"github.com/gorilla/mux"
@ -52,17 +53,57 @@ func Logger(logger log.Logger) ServerOption {
}
}
// Middleware with service middleware option.
func Middleware(m ...middleware.Middleware) ServerOption {
return func(o *Server) {
o.ms = m
}
}
// Filter with HTTP middleware option.
func Filter(filters ...FilterFunc) ServerOption {
return func(o *Server) {
o.filters = filters
}
}
// RequestDecoder with request decoder.
func RequestDecoder(dec DecodeRequestFunc) ServerOption {
return func(o *Server) {
o.dec = dec
}
}
// ResponseEncoder with response encoder.
func ResponseEncoder(en EncodeResponseFunc) ServerOption {
return func(o *Server) {
o.enc = en
}
}
// ErrorEncoder with error encoder.
func ErrorEncoder(en EncodeErrorFunc) ServerOption {
return func(o *Server) {
o.ene = en
}
}
// Server is an HTTP server wrapper.
type Server struct {
*http.Server
ctx context.Context
lis net.Listener
once sync.Once
endpoint *url.URL
err error
network string
address string
endpoint *url.URL
timeout time.Duration
filters []FilterFunc
ms []middleware.Middleware
dec DecodeRequestFunc
enc EncodeResponseFunc
ene EncodeErrorFunc
router *mux.Router
log *log.Helper
}
@ -73,16 +114,25 @@ func NewServer(opts ...ServerOption) *Server {
network: "tcp",
address: ":0",
timeout: 1 * time.Second,
dec: DefaultRequestDecoder,
enc: DefaultResponseEncoder,
ene: DefaultErrorEncoder,
log: log.NewHelper(log.DefaultLogger),
}
for _, o := range opts {
o(srv)
}
srv.router = mux.NewRouter()
srv.Server = &http.Server{Handler: srv}
srv.router = mux.NewRouter()
srv.router.Use(srv.filter())
return srv
}
// Route registers an HTTP route.
func (s *Server) Route(prefix string, filters ...FilterFunc) *Route {
return newRoute(prefix, s, filters...)
}
// Handle registers a new route with a matcher for the URL path.
func (s *Server) Handle(path string, h http.Handler) {
s.router.Handle(path, h)
@ -100,18 +150,35 @@ func (s *Server) HandleFunc(path string, h http.HandlerFunc) {
// ServeHTTP should write reply headers and data to the ResponseWriter and then return.
func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
ctx, cancel := ic.Merge(req.Context(), s.ctx)
defer cancel()
ctx = transport.NewServerContext(ctx, &Transport{
endpoint: s.endpoint.String(),
method: req.RequestURI,
metadata: metadata.New(req.Header),
})
if s.timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, s.timeout)
defer cancel()
s.router.ServeHTTP(res, req)
}
func (s *Server) filter() mux.MiddlewareFunc {
return func(next http.Handler) http.Handler {
next = FilterChain(s.filters...)(next)
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx, cancel := ic.Merge(req.Context(), s.ctx)
defer cancel()
if s.timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, s.timeout)
defer cancel()
}
tr := &Transport{
endpoint: s.endpoint.String(),
path: req.RequestURI,
method: req.Method,
operation: req.RequestURI,
metadata: metadata.New(req.Header),
}
if r := mux.CurrentRoute(req); r != nil {
if path, err := r.GetPathTemplate(); err == nil {
tr.operation = path
}
}
ctx = transport.NewServerContext(ctx, tr)
next.ServeHTTP(w, req.WithContext(ctx))
})
}
s.router.ServeHTTP(res, req.WithContext(ctx))
}
// Endpoint return a real address to registry endpoint.

@ -1,6 +1,8 @@
package http
import (
"context"
"github.com/go-kratos/kratos/v2/metadata"
"github.com/go-kratos/kratos/v2/transport"
)
@ -11,9 +13,11 @@ var (
// Transport is an HTTP transport.
type Transport struct {
endpoint string
method string
metadata metadata.Metadata
endpoint string
path string
method string
operation string
metadata metadata.Metadata
}
// Kind returns the transport kind.
@ -26,14 +30,14 @@ func (tr *Transport) Endpoint() string {
return tr.endpoint
}
// Method returns the transport method.
func (tr *Transport) Method() string {
return tr.method
// Operation returns the transport operation.
func (tr *Transport) Operation() string {
return tr.operation
}
// SetMethod sets the transport method.
func (tr *Transport) SetMethod(method string) {
tr.method = method
// SetOperation sets the transport operation.
func (tr *Transport) SetOperation(operation string) {
tr.operation = operation
}
// Metadata returns the transport metadata.
@ -43,11 +47,27 @@ func (tr *Transport) Metadata() metadata.Metadata {
// WithMetadata with a metadata into transport md.
func (tr *Transport) WithMetadata(md metadata.Metadata) {
if tr.metadata == nil {
tr.metadata = md
return
}
for k, v := range md {
tr.metadata.Set(k, v)
}
}
// Path returns the Transport path from server context.
func Path(ctx context.Context) string {
if tr, ok := transport.FromServerContext(ctx); ok {
if tr, ok := tr.(*Transport); ok {
return tr.path
}
}
return ""
}
// Method returns the Transport method from server context.
func Method(ctx context.Context) string {
if tr, ok := transport.FromServerContext(ctx); ok {
if tr, ok := tr.(*Transport); ok {
return tr.method
}
}
return ""
}

@ -28,8 +28,8 @@ type Transporter interface {
Kind() string
Endpoint() string
Method() string
SetMethod(string)
Operation() string
SetOperation(string)
Metadata() metadata.Metadata
// WithMetadata merge new metadata into transport,
@ -62,19 +62,19 @@ func FromClientContext(ctx context.Context) (tr Transporter, ok bool) {
return
}
// Method returns the Transport method from server context.
func Method(ctx context.Context) string {
// SetOperation set operation into context transport.
func SetOperation(ctx context.Context, method string) {
if tr, ok := FromServerContext(ctx); ok {
return tr.Method()
tr.SetOperation(method)
}
return ""
}
// SetMethod set serviceMethod into context transport.
func SetMethod(ctx context.Context, method string) {
// Operation returns the Transport operation from server context.
func Operation(ctx context.Context) string {
if tr, ok := FromServerContext(ctx); ok {
tr.SetMethod(method)
return tr.Operation()
}
return ""
}
// Metadata returns incoming metadata from server transport.
@ -84,10 +84,3 @@ func Metadata(ctx context.Context) metadata.Metadata {
}
return metadata.Metadata{}
}
// SetMetadata sets outgoing metadata into client transport.
func SetMetadata(ctx context.Context, md metadata.Metadata) {
if tr, ok := FromClientContext(ctx); ok {
tr.WithMetadata(md)
}
}

Loading…
Cancel
Save