// Code generated by protoc-gen-micro // source: {{.File.Name}} package {{goPkgLastElement .File | splitArray ";" | last}} import ( "context" "fmt" "net/http" "reflect" "strings" "github.com/gorilla/mux" micro_api "github.com/unistack-org/micro/v3/api" micro_client "github.com/unistack-org/micro/v3/client" micro_server "github.com/unistack-org/micro/v3/server" micro_client_http "github.com/unistack-org/micro-client-http/v3" ) var ( _ micro_server.Option _ micro_client.Option ) {{- $File := .File }} {{- $ServiceName := .Service.Name | trimSuffix "Service" }} type {{$ServiceName | lowerFirst}}Service struct { c micro_client.Client name string } // Micro client stuff // New{{$ServiceName}}Service create new service client func New{{$ServiceName}}Service(name string, c micro_client.Client) {{$ServiceName}}Service { return &{{$ServiceName | lowerFirst}}Service{c: c, name: name} } {{range .Service.Method}} {{- $reqMethod := .InputType | splitArray "." | last}} {{- $rspMethod := .OutputType | splitArray "." | last}} {{- if and (not .ClientStreaming) (.ServerStreaming) -}} func (c *{{$ServiceName | lowerFirst}}Service) {{.Name}}(ctx context.Context, req *{{$reqMethod}}, opts ...micro_client.CallOption) ({{$ServiceName}}_{{.Name}}Service, error) { {{- else if .ClientStreaming -}} func (c *{{$ServiceName | lowerFirst}}Service) {{.Name}}(ctx context.Context, opts ...micro_client.CallOption) ({{$ServiceName}}_{{.Name}}Service, error) { {{- else -}} func (c *{{$ServiceName | lowerFirst}}Service) {{.Name}}(ctx context.Context, req *{{$reqMethod}}, opts ...micro_client.CallOption) (*{{$rspMethod}}, error) { {{- end }} {{- if not (contains (json (openapiOption .)) "null") }} {{- if (openapiOption .).Responses }} errmap := make(map[string]interface{}, {{ len (openapiOption .).Responses}}) {{- range $k, $v := (openapiOption .).Responses }} errmap["{{$k}}"] = &{{- (getMessageType $File $v.Schema.JsonSchema.Ref).Name }}{} {{- end }} {{- end }} {{- end }} nopts := append(opts, micro_client_http.Method("{{httpVerb .}}"), micro_client_http.Path("{{httpPath .}}"), {{- if not (contains (json (openapiOption .)) "null") }} {{- if (openapiOption .).Responses }} micro_client_http.ErrorMap(errmap), {{- end }} {{- end }} ) {{- if or (.ServerStreaming) (.ClientStreaming)}} stream, err := c.c.Stream(ctx, c.c.NewRequest(c.name, "{{$ServiceName}}.{{.Name}}", &{{$reqMethod}}{}), nopts...) if err != nil { return nil, err } {{- if not .ClientStreaming }} if err := stream.Send(req); err != nil { return nil, err } {{- end}} return &{{$ServiceName | lowerFirst}}Service{{.Name}}{stream}, nil {{- else}} rsp := &{{$rspMethod}}{} err := c.c.Call(ctx, c.c.NewRequest(c.name, "{{$ServiceName}}.{{.Name}}", req), rsp, nopts...) if err != nil { return nil, err } return rsp, nil {{- end}} } {{- if not (contains (json (openapiOption .)) "null") }} {{- if (openapiOption .).Responses }} {{ range $k, $v := (openapiOption .).Responses }} // Error method to satisfy error interface func (e *{{- (getMessageType $File $v.Schema.JsonSchema.Ref).Name }}) Error() string { return fmt.Sprintf("%#v", e) } {{- end }} {{- end }} {{- end }} {{if or (.ServerStreaming) (.ClientStreaming)}} type {{$ServiceName | lowerFirst}}Service{{.Name}} struct { stream micro_client.Stream } {{if and (.ClientStreaming) (not .ServerStreaming)}} func (x *{{$ServiceName | lowerFirst}}Service{{.Name}}) RecvAndClose() (*{{$rspMethod}}, error) { m := &{{$rspMethod}}{} err := x.RecvMsg(m) if err == nil { err = x.Close() } if err != nil { return nil, err } return m, nil } {{- end}} func (x *{{$ServiceName | lowerFirst}}Service{{.Name}}) Close() error { return x.stream.Close() } func (x *{{$ServiceName | lowerFirst}}Service{{.Name}}) Context() context.Context { return x.stream.Context() } func (x *{{$ServiceName | lowerFirst}}Service{{.Name}}) SendMsg(m interface{}) error { return x.stream.Send(m) } func (x *{{$ServiceName | lowerFirst}}Service{{.Name}}) RecvMsg(m interface{}) error { return x.stream.Recv(m) } {{ if .ClientStreaming -}} func (x *{{$ServiceName | lowerFirst}}Service{{.Name}}) Send(m *{{$reqMethod}}) error { return x.stream.Send(m) } {{- end}} {{ if .ServerStreaming -}} func (x *{{$ServiceName | lowerFirst}}Service{{.Name}}) Recv() (*{{$rspMethod}}, error) { m := &{{$rspMethod}}{} if err := x.stream.Recv(m); err != nil { return nil, err } return m, nil } {{- end }} {{- end}} {{- end -}} // Micro server stuff type {{$ServiceName | lowerFirst}}Handler struct { {{$ServiceName}}Handler } {{range .Service.Method }} {{- $reqMethod := .InputType | splitArray "." | last}} {{- $rspMethod := .OutputType | splitArray "." | last}} {{- if or (.ServerStreaming) (.ClientStreaming)}} func (h *{{$ServiceName | lowerFirst}}Handler) {{.Name}}(ctx context.Context, stream micro_server.Stream) error { {{- if not .ClientStreaming}} m := &{{$reqMethod}}{} if err := stream.Recv(m); err != nil { return err } return h.{{$ServiceName}}Handler.{{.Name}}(ctx, m, &{{$ServiceName | lowerFirst}}{{.Name}}Stream{stream}) {{- else}} return h.{{$ServiceName}}Handler.{{.Name}}(ctx, &{{$ServiceName | lowerFirst}}{{.Name}}Stream{stream}) {{- end}} } {{- else}} func (h *{{$ServiceName | lowerFirst}}Handler) {{.Name}}(ctx context.Context, req *{{$reqMethod}}, rsp *{{$rspMethod}}) error { return h.{{$ServiceName}}Handler.{{.Name}}(ctx, req, rsp) } {{- end}} {{if or (.ServerStreaming) (.ClientStreaming)}} type {{$ServiceName}}_{{.Name}}Stream interface { Context() context.Context SendMsg(interface{}) error RecvMsg(interface{}) error {{- if and (.ClientStreaming) (not .ServerStreaming)}} SendAndClose(*{{$rspMethod}}) error {{- end}} Close() error {{- if .ServerStreaming}} Send(*{{$rspMethod}}) error {{- end}} {{- if .ClientStreaming}} Recv() (*{{$reqMethod}}, error) {{- end}} } type {{$ServiceName | lowerFirst}}{{.Name}}Stream struct { stream micro_server.Stream } {{if and (.ClientStreaming) (not .ServerStreaming)}} func (x *{{$ServiceName | lowerFirst}}{{.Name}}Stream) SendAndClose(m *{{$rspMethod}}) error { err := x.SendMsg(m) if err == nil { err = x.stream.Close() } return err } {{- end}} func (x *{{$ServiceName | lowerFirst}}{{.Name}}Stream) Close() error { return x.stream.Close() } func (x *{{$ServiceName | lowerFirst}}{{.Name}}Stream) Context() context.Context { return x.stream.Context() } func (x *{{$ServiceName | lowerFirst}}{{.Name}}Stream) SendMsg(m interface{}) error { return x.stream.Send(m) } func (x *{{$ServiceName | lowerFirst}}{{.Name}}Stream) RecvMsg(m interface{}) error { return x.stream.Recv(m) } {{- if .ServerStreaming}} func (x *{{$ServiceName | lowerFirst}}{{.Name}}Stream) Send(m *{{$rspMethod}}) error { return x.stream.Send(m) } {{- end}} {{if .ClientStreaming}} func (x *{{$ServiceName | lowerFirst}}{{.Name}}Stream) Recv() (*{{$reqMethod}}, error) { m := &{{$reqMethod}}{} if err := x.stream.Recv(m); err != nil { return nil, err } return m, nil } {{- end}} {{- end}} {{- end}} func Register(r *mux.Router, h interface{}, eps []*micro_api.Endpoint) error { v := reflect.ValueOf(h) methods := v.NumMethod() if methods < 1 { return fmt.Errorf("invalid handler specified: %#+v", h) } for _, ep := range eps { idx := strings.Index(ep.Name, ".") if idx < 1 || len(ep.Name) <= idx { return fmt.Errorf("invalid api.Endpoint name: %s", ep.Name) } name := ep.Name[idx+1:] m := v.MethodByName(name) if !m.IsValid() || m.IsZero() { return fmt.Errorf("invalid handler, method %s not found", name) } rh, ok := m.Interface().(func(http.ResponseWriter, *http.Request)) if !ok { return fmt.Errorf("invalid handler: %#+v", m.Interface()) } r.HandleFunc(ep.Path[0], rh).Methods(ep.Method...).Name(ep.Name) } return nil }