github.com/renbou/grpcbridge@v0.0.2-0.20240416012907-bcbd8b12648a/routing/routing.go (about)

     1  // Package routing provides routers for handling gRPC and HTTP requests in grpcbridge.
     2  // Currently, two routers are present with pretty different logic in regard to routing:
     3  //
     4  //  1. [ServiceRouter], which can route gRPC and HTTP requests according to the path definition in gRPC's [PROTOCOL-HTTP2] spec,
     5  //     and only requires information about the target's available service names, not complete method and binding definitions.
     6  //  2. [PatternRouter], which can route HTTP requests according to the path templates defined in gRPC Transcoding's [http.proto],
     7  //     but requires full method and binding definitions for each of a target's services.
     8  //     It is compatible with the routing used in the [gRPC-Gateway] apart from slight security-related changes.
     9  //
    10  // Both of these routers are used by grpcbridge itself to optimize and perform routing in different use-cases,
    11  // such as HTTP-to-gRPC transcoding, gRPC proxying, gRPC-Web bridging, etc.
    12  //
    13  // [PROTOCOL-HTTP2]: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
    14  // [http.proto]: https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
    15  // [gRPC-Gateway]: https://github.com/grpc-ecosystem/grpc-gateway
    16  package routing
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"net/http"
    22  
    23  	"github.com/renbou/grpcbridge/bridgedesc"
    24  	"github.com/renbou/grpcbridge/grpcadapter"
    25  	"google.golang.org/grpc"
    26  	"google.golang.org/grpc/metadata"
    27  	"google.golang.org/grpc/peer"
    28  )
    29  
    30  // for docs
    31  var (
    32  	_ = grpc.Method
    33  	_ = metadata.FromIncomingContext
    34  	_ = peer.FromContext
    35  )
    36  
    37  // GRPCRoute contains the matched route information for a single gRPC request, returned by the RouteGRPC method of the routers.
    38  type GRPCRoute struct {
    39  	Target  *bridgedesc.Target
    40  	Service *bridgedesc.Service
    41  	Method  *bridgedesc.Method
    42  }
    43  
    44  // HTTPRoute contains the matched route information for a single specific HTTP request, returned by the RouteHTTP method of the routers.
    45  type HTTPRoute struct {
    46  	Target  *bridgedesc.Target
    47  	Service *bridgedesc.Service
    48  	Method  *bridgedesc.Method
    49  	Binding *bridgedesc.Binding
    50  	// Matched, URL-decoded path parameters defined by the binding pattern.
    51  	// See https://github.com/googleapis/googleapis/blob/e0677a395947c2f3f3411d7202a6868a7b069a41/google/api/http.proto#L295
    52  	// for information about how exactly different kinds of parameters are decoded.
    53  	PathParams map[string]string
    54  }
    55  
    56  // ErrAlreadyWatching is returned by the Watch() method on routers when a watcher already exists
    57  // for the specified target and a new one should not be created without closing the previous one first.
    58  var ErrAlreadyWatching = errors.New("target already being watched")
    59  
    60  // HTTPRouter is the interface implemented by routers capable of routing HTTP requests.
    61  // RouteHTTP can use any information available in the request to perform routing and
    62  // return a connection to the target as well as the matched route information, including any path parameters.
    63  // Errors returned by RouteHTTP should preferrably be gRPC status errors with HTTP-appropriate codes like NotFound set,
    64  // but they can additionally implement interface { HTTPStatus() int } to return a custom HTTP status code.
    65  type HTTPRouter interface {
    66  	RouteHTTP(*http.Request) (grpcadapter.ClientConn, HTTPRoute, error)
    67  }
    68  
    69  // GRPCRouter is the interface implemented by routers capable of routing gRPC requests.
    70  // Unlike [HTTPRouter], it doesn't receive a request in its raw form, since no such universal form
    71  // exists for gRPC in Go, and instead the incoming gRPC request context is passed.
    72  // The router can use standard gRPC methods such as [grpc.Method], [metadata.FromIncomingContext],
    73  // and [peer.FromContext] to retrieve the necessary information.
    74  // Errors returned by RouteGRPC should be gRPC status errors which can be returned to the client as-is.
    75  type GRPCRouter interface {
    76  	RouteGRPC(context.Context) (grpcadapter.ClientConn, GRPCRoute, error)
    77  }