github.com/lastbackend/toolkit@v0.0.0-20241020043710-cafa37b95aad/protoc-gen-toolkit/gentoolkit/templates/server.go (about) 1 /* 2 Copyright [2014] - [2023] The Last.Backend authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package templates 18 19 // ServerGRPCDefineTpl is the server GRPC define template used for new services. 20 var ServerGRPCDefineTpl = `// Define GRPC services for {{ .GetName }} GRPC server 21 22 type {{ .GetName }}RpcServer interface { 23 {{ range $m := .Methods }} 24 {{ if not $m.IsWebsocket }} 25 {{ if and (not $m.GetServerStreaming) (not $m.GetClientStreaming) }} 26 {{ $m.GetName }}(ctx context.Context, req *{{ $m.RequestType.GoType $m.Service.File.GoPkg.Path }}) (*{{ $m.ResponseType.GoType $m.Service.File.GoPkg.Path }}, error) 27 {{ else }}{{ if not $m.GetClientStreaming }} 28 {{ $m.GetName }}(req *{{ $m.RequestType.GoType $m.Service.File.GoPkg.Path }}, stream {{ $.GetName }}_{{ $m.GetName }}Server) error 29 {{ else }} 30 {{ $m.GetName }}(stream {{ $.GetName }}_{{ $m.GetName }}Server) error 31 {{ end }}{{ end }} 32 {{ end }} 33 {{ end }} 34 } 35 36 type {{ .GetName | ToLower }}GrpcRpcServer struct { 37 {{ .GetName }}RpcServer 38 } 39 40 {{ range $m := .Methods }} 41 {{ if not $m.IsWebsocket }} 42 {{ if and (not $m.GetServerStreaming) (not $m.GetClientStreaming) }} 43 func (h *{{ $.GetName | ToLower }}GrpcRpcServer) {{ $m.GetName }}(ctx context.Context, req *{{ $m.RequestType.GoType $m.Service.File.GoPkg.Path }}) (*{{ $m.ResponseType.GoType $m.Service.File.GoPkg.Path }}, error) { 44 return h.{{ $.GetName }}RpcServer.{{ $m.GetName }}(ctx, req) 45 } 46 {{ else }}{{ if not $m.GetClientStreaming }} 47 func (h *{{ $.GetName | ToLower }}GrpcRpcServer) {{ $m.GetName }}(req *{{ $m.RequestType.GoType $m.Service.File.GoPkg.Path }}, stream {{ $.GetName }}_{{ $m.GetName }}Server) error { 48 return h.{{ $.GetName }}RpcServer.{{ $m.GetName }}(req, stream) 49 } 50 {{ else }} 51 func (h *{{ $.GetName | ToLower }}GrpcRpcServer) {{ $m.GetName }}(stream {{ $.GetName }}_{{ $m.GetName }}Server) error { 52 return h.{{ $.GetName }}RpcServer.{{ $m.GetName }}(stream) 53 } 54 {{ end }}{{ end }} 55 {{ end }} 56 {{ end }} 57 func ({{ $.GetName | ToLower }}GrpcRpcServer) mustEmbedUnimplemented{{ $.GetName }}Server() {} 58 59 func register{{ $.GetName }}GRPCServer(runtime runtime.Runtime, srv {{ $.GetName }}RpcServer) error { 60 runtime.Server().GRPC().RegisterService(&{{ $.GetName | ToLower }}GrpcRpcServer{srv}) 61 return nil 62 } 63 ` 64 65 // ServiceInterfaceDefineTpl is defined service template used for new services. 66 var ServiceInterfaceDefineTpl = `// Define services for {{ .GetName }} HTTP server 67 68 type {{ .GetName }}HTTPService interface { 69 {{ range $m := .Methods }} 70 {{ if not $m.IsWebsocket }} 71 {{ if and (not $m.GetServerStreaming) (not $m.GetClientStreaming) }} 72 {{ $m.GetName }}(ctx context.Context, req *{{ $m.RequestType.GoType $m.Service.File.GoPkg.Path }}) (*{{ $m.ResponseType.GoType $m.Service.File.GoPkg.Path }}, error) 73 {{ end }} 74 {{ end }} 75 {{ end }} 76 } 77 ` 78 79 // ServerHTTPDefineTpl is the server HTTP define template used for new services. 80 var ServerHTTPDefineTpl = `// Define HTTP handlers for Router HTTP server 81 82 {{- range $m := .Methods }} 83 {{- range $binding := $m.Bindings }} 84 {{- if and $.UseWebsocketProxyServer $binding.WebsocketProxy (not $binding.Websocket) }} 85 func (s *service{{ $.GetName | ToCamel }}) handlerWSProxy{{ $.GetName | ToCamel }}{{ $m.GetName | ToCamel }}(ctx context.Context, event tk_ws.Event, c *tk_ws.Client) error { 86 ctx, cancel := context.WithCancel(ctx) 87 defer cancel() 88 89 var protoRequest {{ $binding.RequestType.GoType $binding.Method.Service.File.GoPkg.Path }} 90 var protoResponse {{ $binding.ResponseType.GoType $binding.Method.Service.File.GoPkg.Path }} 91 92 if err := json.Unmarshal(event.Payload, &protoRequest); err != nil { 93 return err 94 } 95 96 callOpts := make([]client.GRPCCallOption, 0) 97 98 if headers := ctx.Value(tk_ws.RequestHeaders); headers != nil { 99 if v, ok := headers.(map[string]string); ok { 100 callOpts = append(callOpts, client.GRPCOptionHeaders(v)) 101 } 102 } 103 104 if err := s.runtime.Client().GRPC().Call(ctx, "{{ $binding.Service }}", "{{ $binding.RpcPath }}", &protoRequest, &protoResponse, callOpts...); err != nil { 105 return err 106 } 107 108 return c.WriteJSON(protoResponse) 109 } 110 {{- end }} 111 {{ if and (not $binding.WebsocketProxy) (not $binding.Websocket) }} 112 func (s *service{{ $.GetName | ToCamel }}) handlerHTTP{{ $.GetName | ToCamel }}{{ $m.GetName | ToCamel }}{{- if $binding.AdditionalBinding }}_{{ $binding.Index }}{{ end }}(w http.ResponseWriter, r *http.Request) { 113 ctx, cancel := context.WithCancel(r.Context()) 114 defer cancel() 115 116 var protoRequest {{ $binding.RequestType.GoType $binding.Method.Service.File.GoPkg.Path }} 117 var protoResponse {{ if and (not $binding.Service) (not $binding.RpcPath) }}*{{ end }}{{ $binding.ResponseType.GoType $binding.Method.Service.File.GoPkg.Path }} 118 119 {{ if or (eq $binding.HttpMethod "http.MethodPost") (eq $binding.HttpMethod "http.MethodPut") (eq $binding.HttpMethod "http.MethodPatch") }} 120 {{ if eq $binding.RawBody "*" }} 121 im, om := tk_http.GetMarshaler(s.runtime.Server().HTTP(), r) 122 123 reader, err := tk_http.NewReader(r.Body) 124 if err != nil { 125 errors.HTTP.InternalServerError(w) 126 return 127 } 128 129 if err := im.NewDecoder(reader).Decode(&protoRequest); err != nil && err != io.EOF { 130 errors.HTTP.BadRequest(w, err.Error()) 131 return 132 } 133 {{ else }} 134 _, om := tk_http.GetMarshaler(s.runtime.Server().HTTP(), r) 135 136 if err := tk_http.SetRawBodyToProto(r, &protoRequest, "{{ $binding.RawBody }}"); err != nil { 137 errors.HTTP.InternalServerError(w) 138 return 139 } 140 141 {{ end }} 142 {{ else }} 143 _, om := tk_http.GetMarshaler(s.runtime.Server().HTTP(), r) 144 145 if err := r.ParseForm(); err != nil { 146 errors.HTTP.InternalServerError(w) 147 return 148 } 149 150 if err := tk_http.ParseRequestQueryParametersToProto(&protoRequest, r.Form); err != nil { 151 errors.HTTP.InternalServerError(w) 152 return 153 } 154 {{ end }} 155 156 {{ range $param := $binding.HttpParams }} 157 if err := tk_http.ParseRequestUrlParametersToProto(r, &protoRequest, "{{ $param | ToTrimRegexFromQueryParameter }}"); err != nil { 158 errors.HTTP.InternalServerError(w) 159 return 160 } 161 {{ end }} 162 163 headers, err := tk_http.PrepareHeaderFromRequest(r) 164 if err != nil { 165 errors.HTTP.InternalServerError(w) 166 return 167 } 168 169 {{ if and $binding.Service $binding.RpcPath }} 170 callOpts := make([]client.GRPCCallOption, 0) 171 callOpts = append(callOpts, client.GRPCOptionHeaders(headers)) 172 173 if err := s.runtime.Client().GRPC().Call(ctx, "{{ $binding.Service }}", "{{ $binding.RpcPath }}", &protoRequest, &protoResponse, callOpts...); err != nil { 174 errors.GrpcErrorHandlerFunc(w, err) 175 return 176 } 177 {{ else }} 178 ctx = tk_http.NewIncomingContext(ctx, headers) 179 180 protoResponse, err = s.runtime.Server().HTTP().GetService().({{ $.GetName }}HTTPService).{{ $binding.RpcMethod }}(ctx, &protoRequest) 181 if err != nil { 182 errors.GrpcErrorHandlerFunc(w, err) 183 return 184 } 185 {{ end }} 186 187 buf, err := om.Marshal(protoResponse) 188 if err != nil { 189 errors.HTTP.InternalServerError(w) 190 return 191 } 192 193 w.Header().Set("Content-Type", om.ContentType()) 194 if proceed, err := tk_http.HandleGRPCResponse(w, r, headers); err != nil || !proceed { 195 return 196 } 197 198 if _, err = w.Write(buf); err != nil { 199 return 200 } 201 } 202 {{- end }} 203 {{- end }} 204 {{- end }} 205 `