gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/api/api.go (about)

     1  package api
     2  
     3  import (
     4  	"errors"
     5  	"regexp"
     6  	"strings"
     7  
     8  	"gitee.com/liuxuezhan/go-micro-v1.18.0/registry"
     9  	"gitee.com/liuxuezhan/go-micro-v1.18.0/server"
    10  )
    11  
    12  // Endpoint is a mapping between an RPC method and HTTP endpoint
    13  type Endpoint struct {
    14  	// RPC Method e.g. Greeter.Hello
    15  	Name string
    16  	// Description e.g what's this endpoint for
    17  	Description string
    18  	// API Handler e.g rpc, proxy
    19  	Handler string
    20  	// HTTP Host e.g example.com
    21  	Host []string
    22  	// HTTP Methods e.g GET, POST
    23  	Method []string
    24  	// HTTP Path e.g /greeter. Expect POSIX regex
    25  	Path []string
    26  }
    27  
    28  // Service represents an API service
    29  type Service struct {
    30  	// Name of service
    31  	Name string
    32  	// The endpoint for this service
    33  	Endpoint *Endpoint
    34  	// Versions of this service
    35  	Services []*registry.Service
    36  }
    37  
    38  func strip(s string) string {
    39  	return strings.TrimSpace(s)
    40  }
    41  
    42  func slice(s string) []string {
    43  	var sl []string
    44  
    45  	for _, p := range strings.Split(s, ",") {
    46  		if str := strip(p); len(str) > 0 {
    47  			sl = append(sl, strip(p))
    48  		}
    49  	}
    50  
    51  	return sl
    52  }
    53  
    54  // Encode encodes an endpoint to endpoint metadata
    55  func Encode(e *Endpoint) map[string]string {
    56  	if e == nil {
    57  		return nil
    58  	}
    59  
    60  	return map[string]string{
    61  		"endpoint":    e.Name,
    62  		"description": e.Description,
    63  		"method":      strings.Join(e.Method, ","),
    64  		"path":        strings.Join(e.Path, ","),
    65  		"host":        strings.Join(e.Host, ","),
    66  		"handler":     e.Handler,
    67  	}
    68  }
    69  
    70  // Decode decodes endpoint metadata into an endpoint
    71  func Decode(e map[string]string) *Endpoint {
    72  	if e == nil {
    73  		return nil
    74  	}
    75  
    76  	return &Endpoint{
    77  		Name:        e["endpoint"],
    78  		Description: e["description"],
    79  		Method:      slice(e["method"]),
    80  		Path:        slice(e["path"]),
    81  		Host:        slice(e["host"]),
    82  		Handler:     e["handler"],
    83  	}
    84  }
    85  
    86  // Validate validates an endpoint to guarantee it won't blow up when being served
    87  func Validate(e *Endpoint) error {
    88  	if e == nil {
    89  		return errors.New("endpoint is nil")
    90  	}
    91  
    92  	if len(e.Name) == 0 {
    93  		return errors.New("name required")
    94  	}
    95  
    96  	for _, p := range e.Path {
    97  		_, err := regexp.CompilePOSIX(p)
    98  		if err != nil {
    99  			return err
   100  		}
   101  	}
   102  
   103  	if len(e.Handler) == 0 {
   104  		return errors.New("invalid handler")
   105  	}
   106  
   107  	return nil
   108  }
   109  
   110  /*
   111  Design ideas
   112  
   113  // Gateway is an api gateway interface
   114  type Gateway interface {
   115  	// Register a http handler
   116  	Handle(pattern string, http.Handler)
   117  	// Register a route
   118  	RegisterRoute(r Route)
   119  	// Init initialises the command line.
   120  	// It also parses further options.
   121  	Init(...Option) error
   122  	// Run the gateway
   123  	Run() error
   124  }
   125  
   126  // NewGateway returns a new api gateway
   127  func NewGateway() Gateway {
   128  	return newGateway()
   129  }
   130  */
   131  
   132  // WithEndpoint returns a server.HandlerOption with endpoint metadata set
   133  //
   134  // Usage:
   135  //
   136  // 	proto.RegisterHandler(service.Server(), new(Handler), api.WithEndpoint(
   137  //		&api.Endpoint{
   138  //			Name: "Greeter.Hello",
   139  //			Path: []string{"/greeter"},
   140  //		},
   141  //	))
   142  func WithEndpoint(e *Endpoint) server.HandlerOption {
   143  	return server.EndpointMetadata(e.Name, Encode(e))
   144  }