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 }