github.com/hduhelp/go-zero@v1.4.3/gateway/internal/descriptorsource.go (about)

     1  package internal
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/fullstorydev/grpcurl"
     9  	"github.com/jhump/protoreflect/desc"
    10  	"google.golang.org/genproto/googleapis/api/annotations"
    11  	"google.golang.org/protobuf/proto"
    12  )
    13  
    14  type Method struct {
    15  	HttpMethod string
    16  	HttpPath   string
    17  	RpcPath    string
    18  }
    19  
    20  // GetMethods returns all methods of the given grpcurl.DescriptorSource.
    21  func GetMethods(source grpcurl.DescriptorSource) ([]Method, error) {
    22  	svcs, err := source.ListServices()
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  
    27  	var methods []Method
    28  	for _, svc := range svcs {
    29  		d, err := source.FindSymbol(svc)
    30  		if err != nil {
    31  			return nil, err
    32  		}
    33  
    34  		switch val := d.(type) {
    35  		case *desc.ServiceDescriptor:
    36  			svcMethods := val.GetMethods()
    37  			for _, method := range svcMethods {
    38  				rpcPath := fmt.Sprintf("%s/%s", svc, method.GetName())
    39  				ext := proto.GetExtension(method.GetMethodOptions(), annotations.E_Http)
    40  				if ext == nil {
    41  					methods = append(methods, Method{
    42  						RpcPath: rpcPath,
    43  					})
    44  					continue
    45  				}
    46  
    47  				httpExt, ok := ext.(*annotations.HttpRule)
    48  				if !ok {
    49  					methods = append(methods, Method{
    50  						RpcPath: rpcPath,
    51  					})
    52  					continue
    53  				}
    54  
    55  				switch rule := httpExt.GetPattern().(type) {
    56  				case *annotations.HttpRule_Get:
    57  					methods = append(methods, Method{
    58  						HttpMethod: http.MethodGet,
    59  						HttpPath:   adjustHttpPath(rule.Get),
    60  						RpcPath:    rpcPath,
    61  					})
    62  				case *annotations.HttpRule_Post:
    63  					methods = append(methods, Method{
    64  						HttpMethod: http.MethodPost,
    65  						HttpPath:   adjustHttpPath(rule.Post),
    66  						RpcPath:    rpcPath,
    67  					})
    68  				case *annotations.HttpRule_Put:
    69  					methods = append(methods, Method{
    70  						HttpMethod: http.MethodPut,
    71  						HttpPath:   adjustHttpPath(rule.Put),
    72  						RpcPath:    rpcPath,
    73  					})
    74  				case *annotations.HttpRule_Delete:
    75  					methods = append(methods, Method{
    76  						HttpMethod: http.MethodDelete,
    77  						HttpPath:   adjustHttpPath(rule.Delete),
    78  						RpcPath:    rpcPath,
    79  					})
    80  				case *annotations.HttpRule_Patch:
    81  					methods = append(methods, Method{
    82  						HttpMethod: http.MethodPatch,
    83  						HttpPath:   adjustHttpPath(rule.Patch),
    84  						RpcPath:    rpcPath,
    85  					})
    86  				default:
    87  					methods = append(methods, Method{
    88  						RpcPath: rpcPath,
    89  					})
    90  				}
    91  			}
    92  		}
    93  	}
    94  
    95  	return methods, nil
    96  }
    97  
    98  func adjustHttpPath(path string) string {
    99  	path = strings.ReplaceAll(path, "{", ":")
   100  	path = strings.ReplaceAll(path, "}", "")
   101  	return path
   102  }