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  `