### Set up gRPC Server Reflection in Go Source: https://github.com/connectrpc/grpcreflect-go/blob/main/README.md This example demonstrates how to set up gRPC server reflection using grpcreflect. It includes mounting both v1 and v1Alpha handlers for broader tool compatibility. Ensure you have the necessary imports for net/http, http2, h2c, and grpcreflect. ```go package main import ( "net/http" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "connectrpc.com/grpcreflect" ) func main() { mux := http.NewServeMux() reflector := grpcreflect.NewStaticReflector( "acme.user.v1.UserService", "acme.group.v1.GroupService", // protoc-gen-connect-go generates package-level constants // for these fully-qualified protobuf service names, so you'd more likely // reference userv1.UserServiceName and groupv1.GroupServiceName. ) mux.Handle(grpcreflect.NewHandlerV1(reflector)) // Many tools still expect the older version of the server reflection API, so // most servers should mount both handlers. mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) // If you don't need to support HTTP/2 without TLS (h2c), you can drop // x/net/http2 and use http.ListenAndServeTLS instead. http.ListenAndServe( ":8080", h2c.NewHandler(mux, &http2.Server{}), ) } ``` -------------------------------- ### Get File Descriptor by Path Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves a file descriptor using its specific path or filename. Useful for inspecting the structure of messages and services defined within a specific proto file. ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/grpcreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://demo.connectrpc.com") stream := client.NewStream(context.Background()) defer stream.Close() // Get file descriptor by filename files, err := stream.FileByFilename("connectrpc/eliza/v1/eliza.proto") if err != nil { log.Fatalf("error: %v", err) } // Process the file descriptors for _, file := range files { fmt.Printf("File: %s\n", file.GetName()) // List messages defined in this file for _, msg := range file.GetMessageType() { fmt.Printf(" Message: %s\n", msg.GetName()) } // List services defined in this file for _, svc := range file.GetService() { fmt.Printf(" Service: %s\n", svc.GetName()) for _, method := range svc.GetMethod() { fmt.Printf(" Method: %s\n", method.GetName()) } } } } ``` -------------------------------- ### ClientStream.FileContainingExtension - Get File Defining Extension Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves the file descriptor for the file that defines a specific extension. Requires the message name and extension number. ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/grpcreflect" "google.golang.org/protobuf/reflect/protoreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://your-server.com") stream := client.NewStream(context.Background()) defer stream.Close() // Get file containing a specific extension messageName := protoreflect.FullName("mypackage.v1.ExtendableMessage") extensionNumber := protoreflect.FieldNumber(100) files, err := stream.FileContainingExtension(messageName, extensionNumber) if err != nil { log.Fatalf("error: %v", err) } for _, file := range files { fmt.Printf("Extension defined in: %s\n", file.GetName()) } } ``` -------------------------------- ### Get File Descriptor for Symbol Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves the file descriptor for a specific symbol, such as a service, message, or enum. The returned slice includes the requested file and its dependencies. ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/grpcreflect" "google.golang.org/protobuf/reflect/protoreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://demo.connectrpc.com") stream := client.NewStream(context.Background()) defer stream.Close() // Get the file descriptor containing a specific symbol symbolName := protoreflect.FullName("connectrpc.eliza.v1.ElizaService") files, err := stream.FileContainingSymbol(symbolName) if err != nil { log.Fatalf("error getting file: %v", err) } // files contains the requested file and potentially its dependencies for _, file := range files { fmt.Printf("File: %s\n", file.GetName()) fmt.Printf("Package: %s\n", file.GetPackage()) fmt.Printf("Services: %v\n", file.GetService()) } } ``` -------------------------------- ### ClientStream.AllExtensionNumbers - Get Extension Numbers for Message Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves all extension tag numbers for a given extendable message type. Requires the message name as a protoreflect.FullName. ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/grpcreflect" "google.golang.org/protobuf/reflect/protoreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://your-server.com") stream := client.NewStream(context.Background()) defer stream.Close() // Get all extension numbers for a message type messageName := protoreflect.FullName("mypackage.v1.ExtendableMessage") extNumbers, err := stream.AllExtensionNumbers(messageName) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("Extensions for %s:\n", messageName) for _, num := range extNumbers { fmt.Printf(" Field number: %d\n", num) } } ``` -------------------------------- ### Create Reflection Client Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Initializes a client that automatically handles fallback from v1 to v1alpha reflection APIs. ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/grpcreflect" ) func main() { // Create a client to query a gRPC server's reflection API client := grpcreflect.NewClient( http.DefaultClient, "https://demo.connectrpc.com", ) // Create a new reflection stream stream := client.NewStream(context.Background()) defer stream.Close() // List all available services names, err := stream.ListServices() if err != nil { log.Fatalf("error listing services: %v", err) } fmt.Printf("Available services: %v\n", names) // Output: Available services: [connectrpc.eliza.v1.ElizaService] } ``` -------------------------------- ### Create v1alpha Reflection Handler Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Constructs a v1alpha reflection handler for backward compatibility with older tools. Mount both v1 and v1alpha handlers to ensure maximum compatibility. ```go package main import ( "net/http" "connectrpc.com/grpcreflect" ) func main() { mux := http.NewServeMux() reflector := grpcreflect.NewStaticReflector("myapp.v1.MyService") // Mount both handlers for maximum tool compatibility mux.Handle(grpcreflect.NewHandlerV1(reflector)) mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) // Both handlers will now respond to reflection queries // v1: /grpc.reflection.v1.ServerReflection/ServerReflectionInfo // v1alpha: /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo http.ListenAndServe(":8080", mux) } ``` -------------------------------- ### Create a Static Reflector in Go Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Use NewStaticReflector for a fixed list of services. This approach relies on the package-global Protobuf registry. ```go package main import ( "net/http" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "connectrpc.com/grpcreflect" ) func main() { mux := http.NewServeMux() // Create a static reflector with your service names // These are fully-qualified Protobuf service names reflector := grpcreflect.NewStaticReflector( "acme.user.v1.UserService", "acme.group.v1.GroupService", // protoc-gen-connect-go generates package-level constants // for these service names, e.g., userv1.UserServiceName ) // Mount both v1 and v1alpha handlers for maximum compatibility mux.Handle(grpcreflect.NewHandlerV1(reflector)) mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) // Start server with HTTP/2 support http.ListenAndServe( ":8080", h2c.NewHandler(mux, &http2.Server{}), ) } ``` -------------------------------- ### Create a v1 Reflection Handler in Go Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Constructs a v1 reflection handler. It supports optional Connect interceptors for custom request handling. ```go package main import ( "net/http" "connectrpc.com/connect" "connectrpc.com/grpcreflect" ) func main() { mux := http.NewServeMux() reflector := grpcreflect.NewStaticReflector("myapp.v1.MyService") // NewHandlerV1 returns (path string, handler http.Handler) // The path is automatically set to the correct gRPC reflection path path, handler := grpcreflect.NewHandlerV1(reflector) mux.Handle(path, handler) // Or use the shorthand that registers directly: // mux.Handle(grpcreflect.NewHandlerV1(reflector)) // With custom Connect handler options path, handler = grpcreflect.NewHandlerV1( reflector, connect.WithInterceptors(/* your interceptors */), ) http.ListenAndServe(":8080", mux) } ``` -------------------------------- ### WithReflectionHost Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Configures the hostname included with reflection requests for routing purposes. ```APIDOC ## WithReflectionHost ### Description Configures the hostname included with reflection requests, which may be used by the server for routing decisions. ### Parameters #### Request Body - **host** (string) - Required - The hostname to be used for reflection requests. ``` -------------------------------- ### List Available Services Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves fully-qualified names for all services exposed by the server. Check for broken streams using IsReflectionStreamBroken if errors occur. ```go package main import ( "context" "fmt" "log" "net/http" "connectrpc.com/grpcreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://demo.connectrpc.com") stream := client.NewStream(context.Background()) defer stream.Close() // ListServices returns []protoreflect.FullName services, err := stream.ListServices() if err != nil { if grpcreflect.IsReflectionStreamBroken(err) { log.Fatal("stream is broken, need to create a new one") } log.Fatalf("error: %v", err) } for _, svc := range services { fmt.Printf("Service: %s\n", svc) } } ``` -------------------------------- ### Create a Configurable Reflector in Go Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Use NewReflector for dynamic service lists or custom resolution logic. This allows integration with service registries or databases. ```go package main import ( "net/http" "connectrpc.com/grpcreflect" "google.golang.org/protobuf/reflect/protoregistry" ) func main() { mux := http.NewServeMux() // Create a dynamic namer that returns service names at runtime namer := grpcreflect.NamerFunc(func() []string { // This could query a service registry or database return []string{ "acme.user.v1.UserService", "acme.group.v1.GroupService", } }) // Create reflector with custom options reflector := grpcreflect.NewReflector( namer, grpcreflect.WithExtensionResolver(protoregistry.GlobalTypes), grpcreflect.WithDescriptorResolver(protoregistry.GlobalFiles), ) mux.Handle(grpcreflect.NewHandlerV1(reflector)) mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) http.ListenAndServe(":8080", mux) } ``` -------------------------------- ### NewHandlerV1 - Create v1 Reflection Handler Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Constructs an implementation of v1 of the gRPC server reflection API. This handler is mounted to the server to allow clients to query service information. ```APIDOC ## POST /grpc.reflection.v1.ServerReflection/ServerReflectionInfo ### Description Provides the gRPC server reflection service, allowing clients to discover available services, methods, and message types. ### Method POST ### Endpoint /grpc.reflection.v1.ServerReflection/ServerReflectionInfo ### Parameters #### Request Body - **ServerReflectionRequest** (message) - Required - The reflection request containing the specific query (e.g., list services, find extension, etc.) ### Response #### Success Response (200) - **ServerReflectionResponse** (message) - The reflection response containing the requested metadata or service definitions. ``` -------------------------------- ### WithReflectionHost - Set Reflection Host Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Configures the hostname included with reflection requests, which may be used by the server for routing decisions. This option is passed during stream creation. ```go package main import ( "context" "net/http" "connectrpc.com/grpcreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://proxy-server.com") // Set the reflection host for routing purposes stream := client.NewStream( context.Background(), grpcreflect.WithReflectionHost("backend-service.internal"), ) defer stream.Close() services, _ := stream.ListServices() _ = services } ``` -------------------------------- ### NewHandlerV1Alpha Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Constructs an implementation of v1alpha of the gRPC server reflection API for backward compatibility. ```APIDOC ## NewHandlerV1Alpha ### Description Constructs an implementation of v1alpha of the gRPC server reflection API, useful for supporting older tools that haven't updated to the v1 API. ### Usage ```go reflector := grpcreflect.NewStaticReflector("myapp.v1.MyService") mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) ``` ``` -------------------------------- ### ClientStream.ListServices Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves the fully-qualified names for all services exposed by the server. ```APIDOC ## ClientStream.ListServices ### Description Retrieves the fully-qualified names for all services exposed by the server. ### Response - **services** ([]protoreflect.FullName) - A list of fully-qualified service names. ``` -------------------------------- ### WithRequestHeaders - Set Custom Request Headers Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Configures custom HTTP headers to be sent when creating a reflection stream. Useful for authentication or passing metadata. ```go package main import ( "context" "net/http" "connectrpc.com/grpcreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://your-server.com") // Create headers with authentication or other metadata headers := http.Header{} headers.Set("Authorization", "Bearer your-token") headers.Set("X-Custom-Header", "custom-value") // Create stream with custom headers stream := client.NewStream( context.Background(), grpcreflect.WithRequestHeaders(headers), ) defer stream.Close() // Use stream normally services, _ := stream.ListServices() _ = services } ``` -------------------------------- ### WithRequestHeaders Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Configures custom HTTP headers to be sent when creating a reflection stream. ```APIDOC ## WithRequestHeaders ### Description Configures custom HTTP headers to be sent when creating a reflection stream, useful for authentication or metadata. ### Parameters #### Request Body - **headers** (http.Header) - Required - The map of HTTP headers to include in the stream request. ``` -------------------------------- ### ClientStream.FileContainingExtension Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves the file descriptor for the file that defines a specific extension. ```APIDOC ## FileContainingExtension ### Description Retrieves the file descriptor for the file that defines a specific extension. ### Parameters #### Path Parameters - **messageName** (protoreflect.FullName) - Required - The full name of the extendable message type. - **extensionNumber** (protoreflect.FieldNumber) - Required - The field number of the extension. ### Response #### Success Response (200) - **files** (slice of FileDescriptorProto) - A list of file descriptors containing the extension definition. ``` -------------------------------- ### ClientStream.FileByFilename Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves the file descriptor for a file with a specific path/name. ```APIDOC ## ClientStream.FileByFilename ### Description Retrieves the file descriptor for a file with a specific path/name. ### Parameters - **filename** (string) - The path/name of the proto file. ### Response - **files** ([]*descriptorpb.FileDescriptorProto) - The requested file descriptor. ``` -------------------------------- ### ClientStream.FileContainingSymbol Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves the file descriptor for the file that defines a given fully-qualified symbol name. ```APIDOC ## ClientStream.FileContainingSymbol ### Description Retrieves the file descriptor for the file that defines a given fully-qualified symbol name (service, message, enum, etc.). ### Parameters - **symbolName** (protoreflect.FullName) - The fully-qualified name of the symbol to look up. ### Response - **files** ([]*descriptorpb.FileDescriptorProto) - The requested file descriptor and its dependencies. ``` -------------------------------- ### ClientStream.AllExtensionNumbers Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Retrieves all extension tag numbers for a given extendable message type. ```APIDOC ## AllExtensionNumbers ### Description Retrieves all extension tag numbers for a given extendable message type. ### Parameters #### Path Parameters - **messageName** (protoreflect.FullName) - Required - The full name of the extendable message type. ### Response #### Success Response (200) - **extNumbers** (slice of int32) - A list of extension field numbers defined for the message. ``` -------------------------------- ### IsReflectionStreamBroken - Check Stream Error Status Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Determines whether an error indicates the stream is broken and cannot be used for further operations. If broken, a new stream must be created. ```go package main import ( "context" "log" "net/http" "connectrpc.com/grpcreflect" ) func main() { client := grpcreflect.NewClient(http.DefaultClient, "https://demo.connectrpc.com") stream := client.NewStream(context.Background()) services, err := stream.ListServices() if err != nil { if grpcreflect.IsReflectionStreamBroken(err) { // Stream is broken - must create a new stream log.Println("Stream broken, creating new stream...") stream.Close() stream = client.NewStream(context.Background()) services, err = stream.ListServices() } else { // Only this operation failed, stream is still usable log.Printf("Operation failed but stream OK: %v", err) } } defer stream.Close() _ = services } ``` -------------------------------- ### IsReflectionStreamBroken Source: https://context7.com/connectrpc/grpcreflect-go/llms.txt Determines whether an error indicates the stream is broken and cannot be used for further operations. ```APIDOC ## IsReflectionStreamBroken ### Description Checks if a given error indicates that the reflection stream is in a broken state and requires re-initialization. ### Parameters #### Path Parameters - **err** (error) - Required - The error returned from a stream operation. ### Response #### Success Response (200) - **isBroken** (boolean) - Returns true if the stream is broken, false otherwise. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.