{"id":29791053,"url":"https://github.com/i2y/hyperway","last_synced_at":"2026-05-20T14:13:49.961Z","repository":{"id":306278241,"uuid":"1023935812","full_name":"i2y/hyperway","owner":"i2y","description":"Go RPC library with dynamic protobuf generation","archived":false,"fork":false,"pushed_at":"2025-07-24T15:02:22.000Z","size":22792,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-24T20:07:39.337Z","etag":null,"topics":["connectrpc","go","golang","grpc","protobuf","rpc"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/i2y.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"docs/SUPPORTED_FEATURES.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-22T00:01:10.000Z","updated_at":"2025-07-24T15:00:58.000Z","dependencies_parsed_at":"2025-07-24T20:19:38.077Z","dependency_job_id":null,"html_url":"https://github.com/i2y/hyperway","commit_stats":null,"previous_names":["i2y/hyperway"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/i2y/hyperway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i2y%2Fhyperway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i2y%2Fhyperway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i2y%2Fhyperway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i2y%2Fhyperway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/i2y","download_url":"https://codeload.github.com/i2y/hyperway/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i2y%2Fhyperway/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267442931,"owners_count":24087899,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["connectrpc","go","golang","grpc","protobuf","rpc"],"created_at":"2025-07-28T00:13:45.508Z","updated_at":"2026-05-20T14:13:49.954Z","avatar_url":"https://github.com/i2y.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hyperway\n\n**Schema-driven RPC development, redefined for Go.**\n\nHyperway bridges code-first agility with schema-first discipline. Your Go structs become the single source of truth, dynamically generating Protobuf schemas at runtime. Serve production-ready gRPC, Connect, gRPC-Web, and JSON-RPC 2.0 APIs from a single codebase, with automatic OpenAPI documentation, while maintaining the ability to export standard .proto files to share your schema-driven API with any team, any language.\n\n## 🚀 Why Hyperway?\n\n### The Traditional Approach\nTraditional gRPC/Connect development follows a schema-first approach:\n1. Writing `.proto` files\n2. Running `protoc` with various plugins\n3. Managing generated code\n4. Rebuilding when schemas change\n\nWhile this approach works well for many use cases, it can be cumbersome for rapid prototyping, small services, or teams that prefer working directly with Go types.\n\n### Benefits of Traditional Proto-First Development\n\nThe traditional approach offers important advantages:\n- **Language-neutral contracts** - `.proto` files serve as universal API documentation\n- **Mature tooling ecosystem** - Linters, breaking change detection, versioning tools\n- **Clear team boundaries** - Explicit contracts for cross-team collaboration\n- **Established workflows** - Well-understood CI/CD patterns\n\n### The Hyperway Approach\nHyperway preserves these benefits while accelerating development:\n1. Define your API using Go structs - your types are the schema\n2. Run your service with automatic schema generation\n3. Export `.proto` files whenever needed for cross-team collaboration\n4. Use all existing proto tooling with your exported schemas\n\nThis hybrid approach maintains the discipline of schema-first development while removing friction from the development cycle. Teams can work rapidly in Go while still providing standard `.proto` files for tooling, documentation, and cross-language support.\n\n### How It Works\nHyperway implements multiple RPC protocols with dynamic capabilities:\n- Generates Protobuf schemas from your Go structs at runtime\n- Supports gRPC (Protobuf), Connect RPC (both Protobuf and JSON), gRPC-Web, and JSON-RPC 2.0\n- Automatically generates OpenAPI 3.0 documentation at `/openapi.json`\n- Maintains wire compatibility with standard clients for all protocols\n- Supports all RPC types: unary, server-streaming, client-streaming, and bidirectional streaming\n- Handles both HTTP/1.1 and HTTP/2 (with h2c support)\n\n## 📊 Performance\n\nHyperway is designed with performance in mind and offers competitive performance compared to connect-go:\n\n### Benchmark Summary\n- **Unary RPCs**: Comparable performance across protocols\n- **Server Streaming**: Improved performance and memory efficiency\n- **Client Streaming**: Competitive performance\n- **Bidirectional Streaming**: Efficient implementation\n- **Memory Usage**: Reduced memory consumption for streaming operations\n\n### Key Performance Features\n- Dynamic schema generation with caching\n- Efficient message parsing using hyperpb\n- Buffer pooling to reduce GC pressure\n- Optimized streaming with configurable flushing\n\nFor detailed benchmarks and performance characteristics, see the [protocol-benchmarks](./protocol-benchmarks) directory.\n\n## ✨ Features\n\n- 📋 **Schema-First**: Go types as your schema definition language\n- 📤 **Proto Export**: Generate standard `.proto` files with language-specific options\n- ⚡ **High Performance**: Uses hyperpb for efficient dynamic protobuf parsing\n- 🔄 **Multi-Protocol**: Supports gRPC, Connect RPC, gRPC-Web, and JSON-RPC 2.0 on the same server\n- 🛡️ **Type-Safe**: Full Go type safety with runtime schema generation\n- 🤝 **Protocol Compatible**: Works with any gRPC, Connect, or gRPC-Web client\n- ✅ **Built-in Validation**: Struct tags for automatic input validation\n- 🔍 **gRPC Reflection**: Service discovery with dynamic schemas\n- 📚 **OpenAPI Generation**: Automatic API documentation\n- 🌐 **Browser Support**: Native gRPC-Web support without proxy\n- 🗜️ **Compression**: Multi-algorithm support (gzip, brotli, zstd) for all protocols\n- 🔁 **All Streaming Types**: Support for server, client, and bidirectional streaming RPCs\n- ⏰ **Well-Known Types**: Support for common Google Well-Known Types (Timestamp, Duration, Empty, Any, Struct, Value, ListValue, FieldMask)\n- 🔌 **Custom Interceptors**: Middleware for logging, auth, metrics, etc.\n- 📦 **Proto3 Optional**: Full support for optional fields\n- 🎯 **Protobuf Editions**: Support for Edition 2023 with features configuration\n- 📏 **Message Size Limits**: Configurable max send/receive message sizes\n\n## 📦 Installation\n\n```bash\n# Library\ngo get github.com/i2y/hyperway\n\n# CLI tool\ngo install github.com/i2y/hyperway/cmd/hyperway@latest\n```\n\n## 🎯 Quick Start\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n    \"net/http\"\n    \n    \"github.com/i2y/hyperway/rpc\"\n    \"golang.org/x/net/http2\"\n    \"golang.org/x/net/http2/h2c\"\n)\n\n// Define your API using Go structs\ntype CreateUserRequest struct {\n    Name  string `json:\"name\" validate:\"required,min=3\"`\n    Email string `json:\"email\" validate:\"required,email\"`\n}\n\ntype CreateUserResponse struct {\n    ID   string `json:\"id\"`\n    Name string `json:\"name\"`\n}\n\n// Write your business logic\nfunc createUser(ctx context.Context, req *CreateUserRequest) (*CreateUserResponse, error) {\n    // Your business logic here\n    return \u0026CreateUserResponse{\n        ID:   \"user-123\",\n        Name: req.Name,\n    }, nil\n}\n\nfunc main() {\n    // Create a service\n    svc := rpc.NewService(\"UserService\", \n        rpc.WithPackage(\"user.v1\"),\n        rpc.WithValidation(true),\n        rpc.WithMaxReceiveMessageSize(10 * 1024 * 1024), // 10MB max receive\n        rpc.WithMaxSendMessageSize(10 * 1024 * 1024),    // 10MB max send\n    )\n    \n    // Register your handlers - function name is automatically extracted\n    if err := rpc.Register(svc, createUser); err != nil {\n        log.Fatal(err)\n    }\n    // Or use explicit naming if preferred\n    // rpc.RegisterAs(svc, \"CreateUser\", createUser)\n    \n    // Create handler - returns a standard http.Handler\n    handler, _ := rpc.NewHandler(svc)\n    \n    // Wrap with h2c to support both HTTP/1.1 and HTTP/2 (required for gRPC)\n    h2s := \u0026http2.Server{}\n    h2Handler := h2c.NewHandler(handler, h2s)\n    \n    // Serve (now supports all protocols including gRPC over HTTP/2)\n    log.Fatal(http.ListenAndServe(\":8080\", h2Handler))\n}\n```\n\n### 🔧 Protocol Configuration\n\nBy default, Hyperway enables Connect, gRPC, and gRPC-Web protocols. You can customize this using several approaches:\n\n#### Using Presets\n```go\n// REST-like APIs (Connect + JSON-RPC)\nsvc := rpc.NewService(\"UserService\",\n    rpc.WithPreset(rpc.PresetREST),\n)\n\n// gRPC ecosystem (gRPC + gRPC-Web)\nsvc := rpc.NewService(\"UserService\",\n    rpc.WithPreset(rpc.PresetGRPC),\n)\n\n// All protocols enabled\nsvc := rpc.NewService(\"UserService\",\n    rpc.WithPreset(rpc.PresetAll),\n)\n\n// Minimal (Connect only)\nsvc := rpc.NewService(\"UserService\",\n    rpc.WithPreset(rpc.PresetMinimal),\n)\n```\n\n#### Individual Protocol Control\n```go\n// Enable specific protocols\nsvc := rpc.NewService(\"UserService\",\n    rpc.WithConnect(true, true),        // Allow both JSON and Proto\n    rpc.WithGRPC(true),                 // Enable with reflection\n    rpc.WithJSONRPC(\"/api/jsonrpc\", 10), // Path and batch limit\n)\n\n// Disable specific protocols while keeping others\nsvc := rpc.NewService(\"UserService\",\n    rpc.DisableGRPCWeb(),  // Disable only gRPC-Web\n)\n```\n\n#### Fluent Configuration Builder\n```go\n// Use the fluent builder for complex configurations\nconfig := rpc.ConfigureProtocols().\n    Connect(true, true).\n    GRPC(true).\n    JSONRPC(\"/api/jsonrpc\", 100).\n    Build()\n\nsvc := rpc.NewService(\"UserService\", config)\n```\n\n## 🧪 Testing Your Service\n\nYour service automatically supports multiple protocols and provides OpenAPI documentation:\n\n### Connect RPC (JSON format)\n```bash\ncurl -X POST http://localhost:8080/user.v1.UserService/CreateUser \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Alice\",\"email\":\"alice@example.com\"}'\n```\n\n### JSON-RPC 2.0\n```bash\n# Note: Requires JSON-RPC to be enabled (see Protocol Configuration above)\ncurl -X POST http://localhost:8080/api/jsonrpc \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"jsonrpc\": \"2.0\",\n    \"method\": \"UserService.CreateUser\",\n    \"params\": {\"name\":\"Alice\",\"email\":\"alice@example.com\"},\n    \"id\": 1\n  }'\n```\n\n### gRPC (with reflection)\n```bash\ngrpcurl -plaintext -d '{\"name\":\"Bob\",\"email\":\"bob@example.com\"}' \\\n  localhost:8080 user.v1.UserService/CreateUser\n```\n\n### Connect Protocol (JSON)\n```bash\ncurl -X POST http://localhost:8080/user.v1.UserService/CreateUser \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Connect-Protocol-Version: 1\" \\\n  -d '{\"name\":\"Charlie\",\"email\":\"charlie@example.com\"}'\n```\n\n### Connect Protocol (Protobuf)\n```bash\n# Using buf curl for Connect protocol testing\nbuf curl --protocol connect \\\n  --http2-prior-knowledge \\\n  --data '{\"name\":\"David\",\"email\":\"david@example.com\"}' \\\n  http://localhost:8080/user.v1.UserService/CreateUser\n```\n\n### OpenAPI Documentation\n```bash\n# Get OpenAPI 3.0 specification\ncurl http://localhost:8080/openapi.json\n\n# View in Swagger UI or any OpenAPI viewer\n# The spec includes all your RPC methods with request/response schemas\n```\n\n## 🔄 The Hybrid Approach: Schema-Driven Development in Go\n\nHyperway redefines schema-driven development for the Go ecosystem:\n\n### 1. Define Your Schema in Go\n```go\ntype User struct {\n    ID    string `json:\"id\"`\n    Name  string `json:\"name\"`\n    Email string `json:\"email\"`\n}\n```\nYour Go types ARE the schema - type-safe, validated, and version-controlled with your code.\n\n### 2. Runtime Schema Generation\nHyperway automatically generates Protobuf schemas from your types at runtime, maintaining full wire compatibility with standard gRPC/Connect clients.\n\n### 3. Export Schemas for Cross-Team Collaboration\n```bash\n# Generate standard .proto files from your running service\nhyperway proto export --endpoint localhost:8080 --output ./proto\n\n# Export with language-specific options (no manual editing needed!)\nhyperway proto export --endpoint localhost:8080 \\\n  --go-package \"github.com/example/api;apiv1\" \\\n  --java-package \"com.example.api\"\n```\n\nNow share your schema-driven API with any team:\n- Client SDK generation in any language\n- API documentation and contracts\n- Language-specific options are automatically added\n- Schema registries (BSR, private repos)\n- Standard protobuf tooling compatibility\n\nThis hybrid approach delivers the discipline of schema-first design with the agility of Go-native development.\n\n## 🛠️ CLI Tool\n\n```bash\n# Export proto files from a running service\nhyperway proto export --endpoint http://localhost:8080 --output ./proto\n\n# Export with language-specific options (no manual editing needed!)\nhyperway proto export --endpoint http://localhost:8080 \\\n  --go-package \"github.com/example/api;apiv1\" \\\n  --java-package \"com.example.api\" \\\n  --csharp-namespace \"Example.Api\"\n\n# Export as ZIP archive with options\nhyperway proto export --endpoint http://localhost:8080 \\\n  --format zip --output api.zip \\\n  --go-package \"github.com/example/api;apiv1\"\n\n# See all available language options\nhyperway proto export --help\n```\n\n## 📚 Advanced Usage\n\n### Complex Types\n\nHyperway supports all Go types you need:\n\n```go\ntype Order struct {\n    ID        string                 `json:\"id\"`\n    Items     []OrderItem           `json:\"items\"`\n    Metadata  map[string]string     `json:\"metadata\"`\n    Customer  *Customer             `json:\"customer,omitempty\"`\n    Status    OrderStatus           `json:\"status\"`\n    CreatedAt time.Time             `json:\"created_at\"`\n}\n```\n\n### Well-Known Types\n\nHyperway supports the most commonly used Google Well-Known Types:\n\n```go\nimport (\n    \"google.golang.org/protobuf/types/known/structpb\"\n    \"google.golang.org/protobuf/types/known/fieldmaskpb\"\n)\n\ntype UpdateRequest struct {\n    // Dynamic configuration using Struct\n    Config *structpb.Struct `json:\"config\"`\n    \n    // Partial updates using FieldMask\n    UpdateMask *fieldmaskpb.FieldMask `json:\"update_mask\"`\n    \n    // Mixed-type values\n    Settings map[string]*structpb.Value `json:\"settings\"`\n}\n```\n\n### Validation\n\nUse struct tags for automatic validation:\n\n```go\ntype RegisterRequest struct {\n    Username string `json:\"username\" validate:\"required,alphanum,min=3,max=20\"`\n    Password string `json:\"password\" validate:\"required,min=8,containsany=!@#$%\"`\n    Email    string `json:\"email\" validate:\"required,email\"`\n    Age      int    `json:\"age\" validate:\"required,min=13,max=120\"`\n}\n```\n\n### Real-World Example\n\nHere's a more complete example showing various features:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"net/http\"\n    \"time\"\n    \n    \"github.com/i2y/hyperway/rpc\"\n    \"golang.org/x/net/http2\"\n    \"golang.org/x/net/http2/h2c\"\n)\n\n// Domain models with validation and well-known types\ntype CreatePostRequest struct {\n    Title     string    `json:\"title\" validate:\"required,min=5,max=200\"`\n    Content   string    `json:\"content\" validate:\"required,min=10\"`\n    AuthorID  string    `json:\"author_id\" validate:\"required,uuid\"`\n    Tags      []string  `json:\"tags\" validate:\"max=10,dive,min=2,max=20\"`\n    Published bool      `json:\"published\"`\n    Metadata  map[string]string `json:\"metadata,omitempty\"`\n}\n\ntype Post struct {\n    ID          string            `json:\"id\"`\n    Title       string            `json:\"title\"`\n    Content     string            `json:\"content\"`\n    AuthorID    string            `json:\"author_id\"`\n    Tags        []string          `json:\"tags\"`\n    Published   bool              `json:\"published\"`\n    PublishedAt *time.Time        `json:\"published_at,omitempty\"` // Optional timestamp\n    CreatedAt   time.Time         `json:\"created_at\"`             // Required timestamp\n    UpdatedAt   time.Time         `json:\"updated_at\"`\n    TTL         *time.Duration    `json:\"ttl,omitempty\"`          // Optional duration\n    Metadata    map[string]string `json:\"metadata\"`\n}\n\n// Service implementation\ntype BlogService struct {\n    // your database, cache, etc.\n}\n\nfunc (s *BlogService) CreatePost(ctx context.Context, req *CreatePostRequest) (*Post, error) {\n    // Business logic here\n    now := time.Now()\n    post := \u0026Post{\n        ID:        generateID(),\n        Title:     req.Title,\n        Content:   req.Content,\n        AuthorID:  req.AuthorID,\n        Tags:      req.Tags,\n        Published: req.Published,\n        CreatedAt: now,\n        UpdatedAt: now,\n        Metadata:  req.Metadata,\n    }\n    \n    if req.Published {\n        post.PublishedAt = \u0026now\n        ttl := 30 * 24 * time.Hour // 30 days\n        post.TTL = \u0026ttl\n    }\n    \n    // Save to database...\n    \n    return post, nil\n}\n\nfunc main() {\n    // Create blog service\n    blogService := \u0026BlogService{}\n    \n    // Create RPC service with interceptors\n    svc := rpc.NewService(\"BlogService\",\n        rpc.WithPackage(\"blog.v1\"),\n        rpc.WithValidation(true),\n        rpc.WithReflection(true),\n        rpc.WithInterceptor(\u0026rpc.RecoveryInterceptor{}),\n        rpc.WithInterceptor(\u0026rpc.TimeoutInterceptor{Timeout: 30*time.Second}),\n    )\n    \n    // Register methods - no need to specify types!\n    if err := rpc.Register(svc, blogService.CreatePost); err != nil {\n        log.Fatal(err)\n    }\n    \n    // Create handler and serve\n    handler, err := rpc.NewHandler(svc)\n    if err != nil {\n        log.Fatal(err)\n    }\n    \n    // Wrap with h2c for HTTP/2 support (required for gRPC)\n    h2s := \u0026http2.Server{}\n    h2Handler := h2c.NewHandler(handler, h2s)\n    \n    log.Println(\"Blog service running on :8080\")\n    log.Println(\"- Connect RPC: POST http://localhost:8080/blog.v1.BlogService/CreatePost\")\n    log.Println(\"- gRPC: localhost:8080 (with reflection)\")\n    log.Fatal(http.ListenAndServe(\":8080\", h2Handler))\n}\n```\n\n### Multiple Services\n\n```go\n// Create multiple services\nuserSvc := rpc.NewService(\"UserService\", rpc.WithPackage(\"api.v1\"))\nauthSvc := rpc.NewService(\"AuthService\", rpc.WithPackage(\"api.v1\"))\nadminSvc := rpc.NewService(\"AdminService\", rpc.WithPackage(\"api.v1\"))\n\n// Register handlers\n// Automatic function name extraction\nrpc.Register(userSvc, createUser)    // Registers as \"CreateUser\"\nrpc.Register(userSvc, getUser)       // Registers as \"GetUser\"\nrpc.Register(authSvc, login)         // Registers as \"Login\"\nrpc.Register(adminSvc, deleteUser)   // Registers as \"DeleteUser\"\n\n// Serve all services on one port\nhandler, _ := rpc.NewHandler(userSvc, authSvc, adminSvc)\n```\n\n### Type-Safe Registration API\n\nHyperway provides a type-safe registration API with automatic function name extraction:\n\n```go\n// Automatic name extraction from function names\nrpc.Register(svc, createUser)        // Registers as \"CreateUser\"\nrpc.Register(svc, getUserByID)       // Registers as \"GetUserByID\"\nrpc.Register(svc, service.UpdateProfile)  // Registers as \"UpdateProfile\"\n\n// Explicit naming when needed\nrpc.RegisterAs(svc, \"CustomName\", myHandler)\n\n// Streaming methods also support automatic naming\nrpc.RegisterServerStream(svc, watchEvents)   // Registers as \"WatchEvents\"\nrpc.RegisterClientStream(svc, uploadFiles)   // Registers as \"UploadFiles\"\nrpc.RegisterBidiStream(svc, chatHandler)     // Registers as \"ChatHandler\"\n```\n\nThe registration functions use Go generics to maintain full type safety at compile time, preventing runtime type errors while keeping the API clean and simple.\n\n### Batch Registration\n\nFor services with many methods, Hyperway provides batch registration capabilities:\n\n#### Register Multiple Methods at Once\n```go\n// Define methods with explicit types\nsvc.RegisterAll(\n    rpc.Unary(\"CreateUser\", createUser),\n    rpc.Unary(\"GetUser\", getUser),\n    rpc.ServerStreamDef(\"WatchUsers\", watchUsers),\n    rpc.ClientStreamDef(\"ImportUsers\", importUsers),\n    rpc.BidiStreamDef(\"UserChat\", userChat),\n)\n```\n\n#### Method Groups for Organization\n```go\n// Group related methods\nuserMethods := rpc.Group().\n    Add(rpc.Unary(\"Create\", userService.Create)).\n    Add(rpc.Unary(\"Get\", userService.Get)).\n    Add(rpc.Unary(\"Update\", userService.Update)).\n    Add(rpc.Unary(\"Delete\", userService.Delete))\n\n// Register the group\nuserMethods.Register(svc)\n```\n\n#### Service Registrar Pattern\n```go\n// Implement ServiceRegistrar interface\ntype UserService struct {\n    db Database\n}\n\nfunc (s *UserService) RegisterMethods(svc *rpc.Service) error {\n    return svc.RegisterAll(\n        rpc.Unary(\"CreateUser\", s.CreateUser),\n        rpc.Unary(\"GetUser\", s.GetUser),\n        rpc.ServerStreamDef(\"WatchUsers\", s.WatchUsers),\n    )\n}\n\n// Register all methods from the service\nuserService := \u0026UserService{db: db}\nsvc.RegisterService(userService)\n```\n\n### Streaming RPCs\n\n#### Server Streaming\n\n```go\n// Server sends multiple responses to client\nfunc (s *Service) WatchEvents(ctx context.Context, req *WatchRequest, stream rpc.ServerStream[*Event]) error {\n    for i := 0; i \u003c 10; i++ {\n        event := \u0026Event{\n            ID:      fmt.Sprintf(\"event-%d\", i),\n            Message: fmt.Sprintf(\"Event %d\", i),\n        }\n        if err := stream.Send(event); err != nil {\n            return err\n        }\n        time.Sleep(100 * time.Millisecond)\n    }\n    return nil\n}\n\n// Register: rpc.RegisterServerStream(svc, service.WatchEvents)  // Auto-registers as \"WatchEvents\"\n```\n\n#### Client Streaming\n\n```go\n// Client sends multiple requests, server sends single response\nfunc (s *Service) UploadFiles(ctx context.Context, stream rpc.ClientStream[*FileChunk]) (*UploadResult, error) {\n    var totalSize int64\n    for {\n        chunk, err := stream.Recv()\n        if err == io.EOF {\n            break\n        }\n        if err != nil {\n            return nil, err\n        }\n        totalSize += int64(len(chunk.Data))\n    }\n    return \u0026UploadResult{TotalSize: totalSize}, nil\n}\n\n// Register: rpc.RegisterClientStream(svc, service.UploadFiles)  // Auto-registers as \"UploadFiles\"\n```\n\n#### Bidirectional Streaming\n\n```go\n// Both client and server send multiple messages\nfunc (s *Service) Chat(ctx context.Context, stream rpc.BidiStream[*ChatMessage, *ChatResponse]) error {\n    for {\n        msg, err := stream.Recv()\n        if err == io.EOF {\n            return nil\n        }\n        if err != nil {\n            return err\n        }\n        \n        response := \u0026ChatResponse{\n            Message: fmt.Sprintf(\"Echo: %s\", msg.Text),\n        }\n        if err := stream.Send(response); err != nil {\n            return err\n        }\n    }\n}\n\n// Register: rpc.RegisterBidiStream(svc, service.Chat)  // Auto-registers as \"Chat\"\n```\n\n### Error Handling\n\nHyperway provides a fluent error builder API for creating rich, detailed errors:\n\n#### Error Builder Pattern\n```go\n// Simple error with code and message\nreturn rpc.InvalidArgument(\"email is required\").Build()\n\n// Error with additional details\nreturn rpc.NotFound(\"user not found\").\n    Detail(\"user_id\", userID).\n    Detail(\"searched_in\", \"primary_db\").\n    Build()\n\n// Error with formatted message\nreturn rpc.Internal(\"database error\").\n    Messagef(\"failed to connect to %s:%d\", host, port).\n    Detail(\"retry_after\", \"5s\").\n    Build()\n\n// Custom error building\nreturn rpc.NewErrorBuilder().\n    Code(rpc.CodeResourceExhausted).\n    Message(\"quota exceeded\").\n    Detail(\"limit\", 1000).\n    Detail(\"current\", 1050).\n    Build()\n```\n\n#### Convenience Error Constructors\n```go\n// All common error types have convenience constructors\nrpc.InvalidArgument(\"message\")     // Invalid input\nrpc.NotFound(\"message\")            // Resource not found  \nrpc.AlreadyExists(\"message\")       // Resource already exists\nrpc.PermissionDenied(\"message\")    // Insufficient permissions\nrpc.Unauthenticated(\"message\")     // Authentication required\nrpc.ResourceExhausted(\"message\")   // Quota/limit exceeded\nrpc.FailedPrecondition(\"message\")  // Operation prerequisites not met\nrpc.Aborted(\"message\")             // Operation aborted\nrpc.OutOfRange(\"message\")          // Value out of range\nrpc.Unimplemented(\"message\")       // Feature not implemented\nrpc.Internal(\"message\")            // Internal server error\nrpc.Unavailable(\"message\")         // Service unavailable\nrpc.DataLoss(\"message\")            // Data loss or corruption\nrpc.DeadlineExceeded(\"message\")    // Operation timeout\n```\n\n#### Validation Error Collection\n```go\nfunc validateUser(user *User) error {\n    collector := rpc.NewErrorCollector()\n    \n    if user.Email == \"\" {\n        collector.Add(\"email\", \"email is required\")\n    } else if !isValidEmail(user.Email) {\n        collector.Add(\"email\", \"invalid email format\")\n    }\n    \n    if user.Age \u003c 18 {\n        collector.Addf(\"age\", \"must be at least %d years old\", 18)\n    }\n    \n    if collector.HasErrors() {\n        return collector.AsError()  // Returns error with all validation issues\n    }\n    \n    return nil\n}\n```\n\n### Context Manipulation\n\nHyperway provides a fluent API for working with request/response headers and trailers:\n\n#### Basic Context Operations\n```go\nfunc myHandler(ctx context.Context, req *Request) (*Response, error) {\n    // Fluent API for headers and trailers\n    rpc.Context(ctx).\n        SetHeader(\"X-Request-ID\", requestID).\n        SetHeader(\"X-Version\", \"1.0.0\").\n        SetTrailer(\"X-Processing-Time\", processingTime)\n    \n    // Get request headers\n    helper := rpc.Context(ctx)\n    clientID := helper.GetHeader(\"X-Client-ID\")\n    authToken := helper.GetHeader(\"Authorization\")\n    \n    // Get request metadata\n    userAgent := helper.GetMetadata(\"user-agent\")\n    \n    return \u0026Response{...}, nil\n}\n```\n\n#### Headers and Trailers\n```go\nfunc streamingHandler(ctx context.Context, req *Request, stream rpc.ServerStream[Response]) error {\n    helper := rpc.Context(ctx)\n    \n    // Set response headers (must be before first Send)\n    helper.SetHeaders(map[string]string{\n        \"X-Stream-ID\": streamID,\n        \"X-Total-Items\": strconv.Itoa(totalItems),\n    })\n    \n    // Stream responses...\n    for _, item := range items {\n        if err := stream.Send(item); err != nil {\n            return err\n        }\n    }\n    \n    // Set trailers (after all sends)\n    helper.SetTrailers(map[string]string{\n        \"X-Items-Sent\": strconv.Itoa(sentCount),\n        \"X-Duration\": duration.String(),\n    })\n    \n    return nil\n}\n```\n\n#### Request Validation with Context\n```go\nfunc protectedHandler(ctx context.Context, req *Request) (*Response, error) {\n    // Validate required headers\n    err := rpc.Context(ctx).\n        RequireHeader(\"Authorization\", \"auth token required\").\n        RequireHeader(\"X-API-Key\", \"API key required\").\n        Validate()\n    \n    if err != nil {\n        return nil, err\n    }\n    \n    // Process request...\n    return \u0026Response{...}, nil\n}\n```\n\n#### Complete Example with All Streaming Types\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"io\"\n    \"log\"\n    \"net/http\"\n    \"time\"\n    \n    \"github.com/i2y/hyperway/rpc\"\n    \"golang.org/x/net/http2\"\n    \"golang.org/x/net/http2/h2c\"\n)\n\n// Request/Response types\ntype WatchRequest struct {\n    Filter string `json:\"filter\"`\n}\n\ntype Event struct {\n    ID      string    `json:\"id\"`\n    Message string    `json:\"message\"`\n    Time    time.Time `json:\"time\"`\n}\n\ntype FileChunk struct {\n    Name string `json:\"name\"`\n    Data []byte `json:\"data\"`\n}\n\ntype UploadResult struct {\n    TotalSize int64 `json:\"total_size\"`\n}\n\ntype ChatMessage struct {\n    Text string `json:\"text\"`\n}\n\ntype ChatResponse struct {\n    Message string `json:\"message\"`\n}\n\n// Service implementation\ntype StreamService struct{}\n\n// Server streaming\nfunc (s *StreamService) WatchEvents(ctx context.Context, req *WatchRequest, stream rpc.ServerStream[*Event]) error {\n    for i := 0; i \u003c 5; i++ {\n        event := \u0026Event{\n            ID:      fmt.Sprintf(\"event-%d\", i),\n            Message: fmt.Sprintf(\"Filtered by: %s\", req.Filter),\n            Time:    time.Now(),\n        }\n        if err := stream.Send(event); err != nil {\n            return err\n        }\n        time.Sleep(100 * time.Millisecond)\n    }\n    return nil\n}\n\n// Client streaming\nfunc (s *StreamService) UploadFiles(ctx context.Context, stream rpc.ClientStream[*FileChunk]) (*UploadResult, error) {\n    var totalSize int64\n    for {\n        chunk, err := stream.Recv()\n        if err == io.EOF {\n            break\n        }\n        if err != nil {\n            return nil, err\n        }\n        totalSize += int64(len(chunk.Data))\n    }\n    return \u0026UploadResult{TotalSize: totalSize}, nil\n}\n\n// Bidirectional streaming\nfunc (s *StreamService) Chat(ctx context.Context, stream rpc.BidiStream[*ChatMessage, *ChatResponse]) error {\n    for {\n        msg, err := stream.Recv()\n        if err == io.EOF {\n            return nil\n        }\n        if err != nil {\n            return err\n        }\n        \n        response := \u0026ChatResponse{\n            Message: fmt.Sprintf(\"Server says: %s\", msg.Text),\n        }\n        if err := stream.Send(response); err != nil {\n            return err\n        }\n    }\n}\n\nfunc main() {\n    service := \u0026StreamService{}\n    \n    // Create service\n    svc := rpc.NewService(\"StreamService\",\n        rpc.WithPackage(\"stream.v1\"),\n        rpc.WithReflection(true),\n    )\n    \n    // Register all streaming methods\n    // Automatic function name extraction for streaming methods\n    rpc.MustRegisterServerStream(svc, service.WatchEvents)  // Registers as \"WatchEvents\"\n    rpc.MustRegisterClientStream(svc, service.UploadFiles)  // Registers as \"UploadFiles\"\n    rpc.MustRegisterBidiStream(svc, service.Chat)           // Registers as \"Chat\"\n    \n    // Create handler and serve\n    handler, err := rpc.NewHandler(svc)\n    if err != nil {\n        log.Fatal(err)\n    }\n    \n    // Wrap with h2c for HTTP/2 support (required for gRPC)\n    h2s := \u0026http2.Server{}\n    h2Handler := h2c.NewHandler(handler, h2s)\n    \n    log.Println(\"Streaming service running on :8080\")\n    log.Fatal(http.ListenAndServe(\":8080\", h2Handler))\n}\n```\n\n### Advanced Registration (Optional)\n\nFor more control, you can use the builder pattern:\n\n```go\n// Use the builder pattern for additional options\nrpc.MustRegisterMethod(svc,\n    rpc.NewMethod(\"CreateUser\", createUser).\n        Validate(true).\n        WithInterceptors(customInterceptor),\n)\n```\n\n### Interceptors/Middleware\n\n```go\n// Add logging, auth, rate limiting, etc.\nsvc := rpc.NewService(\"MyService\",\n    rpc.WithInterceptor(\u0026rpc.LoggingInterceptor{}),\n    rpc.WithInterceptor(\u0026rpc.RecoveryInterceptor{}),\n)\n```\n\n### HTTP Middleware and Handler Composition\n\nHyperway's handler implements the standard `http.Handler` interface, making it fully compatible with Go's HTTP ecosystem. This means you can:\n- Use any standard net/http middleware\n- Combine it with other HTTP handlers\n- Integrate with existing HTTP routers and frameworks\n- **Pass context values from middleware to RPC handlers**\n\n#### Context Propagation\n\nHTTP middleware can add values to the request context, and these values will be accessible in your RPC handlers:\n\n```go\n// Middleware that adds context values\nfunc contextMiddleware(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        // Add request ID\n        ctx := context.WithValue(r.Context(), \"request-id\", generateRequestID())\n        \n        // Add user info from auth header\n        if userID := extractUserID(r.Header.Get(\"Authorization\")); userID != \"\" {\n            ctx = context.WithValue(ctx, \"user-id\", userID)\n        }\n        \n        // Pass the enriched context to the next handler\n        next.ServeHTTP(w, r.WithContext(ctx))\n    })\n}\n\n// RPC handler can access context values\nfunc createOrder(ctx context.Context, req *CreateOrderRequest) (*CreateOrderResponse, error) {\n    // Get values from context\n    requestID, _ := ctx.Value(\"request-id\").(string)\n    userID, _ := ctx.Value(\"user-id\").(string)\n    \n    log.Printf(\"Processing order for user %s (request: %s)\", userID, requestID)\n    \n    // Your business logic here...\n    return \u0026CreateOrderResponse{\n        OrderID:   generateOrderID(),\n        RequestID: requestID,\n    }, nil\n}\n\n// Logging middleware with request tracking\nfunc loggingMiddleware(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        start := time.Now()\n        requestID := generateRequestID()\n        \n        // Add request ID to context for correlation\n        ctx := context.WithValue(r.Context(), \"request-id\", requestID)\n        \n        log.Printf(\"[%s] Started %s %s\", requestID, r.Method, r.URL.Path)\n        \n        // Wrap ResponseWriter to capture status\n        wrapped := \u0026responseWriter{ResponseWriter: w, statusCode: http.StatusOK}\n        next.ServeHTTP(wrapped, r.WithContext(ctx))\n        \n        log.Printf(\"[%s] Completed with %d in %v\", \n            requestID, wrapped.statusCode, time.Since(start))\n    })\n}\n\n// Auth middleware with context enrichment\nfunc authMiddleware(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        token := r.Header.Get(\"Authorization\")\n        if token == \"\" {\n            http.Error(w, \"Unauthorized\", http.StatusUnauthorized)\n            return\n        }\n        \n        // Validate token and extract user info\n        userInfo, err := validateToken(token)\n        if err != nil {\n            http.Error(w, \"Invalid token\", http.StatusUnauthorized)\n            return\n        }\n        \n        // Add user info to context\n        ctx := context.WithValue(r.Context(), \"user\", userInfo)\n        ctx = context.WithValue(ctx, \"user-id\", userInfo.ID)\n        \n        next.ServeHTTP(w, r.WithContext(ctx))\n    })\n}\n\n```\n\n#### Complete Example\n\nHere's a complete example showing middleware composition and context propagation:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"net/http\"\n    \"time\"\n    \n    \"github.com/i2y/hyperway/rpc\"\n    \"github.com/google/uuid\"\n    \"golang.org/x/net/http2\"\n    \"golang.org/x/net/http2/h2c\"\n)\n\n// Request/Response types\ntype CreateOrderRequest struct {\n    ProductID string `json:\"product_id\" validate:\"required\"`\n    Quantity  int    `json:\"quantity\" validate:\"required,min=1\"`\n}\n\ntype CreateOrderResponse struct {\n    OrderID   string `json:\"order_id\"`\n    UserID    string `json:\"user_id\"`\n    RequestID string `json:\"request_id\"`\n}\n\n// Business logic that uses context values\nfunc createOrder(ctx context.Context, req *CreateOrderRequest) (*CreateOrderResponse, error) {\n    // Access context values set by middleware\n    requestID, _ := ctx.Value(\"request-id\").(string)\n    userID, _ := ctx.Value(\"user-id\").(string)\n    \n    log.Printf(\"[%s] Creating order for user %s: %d x %s\", \n        requestID, userID, req.Quantity, req.ProductID)\n    \n    // Create order...\n    orderID := fmt.Sprintf(\"order-%s\", uuid.New().String()[:8])\n    \n    return \u0026CreateOrderResponse{\n        OrderID:   orderID,\n        UserID:    userID,\n        RequestID: requestID,\n    }, nil\n}\n\nfunc main() {\n    // Create service\n    svc := rpc.NewService(\"OrderService\",\n        rpc.WithPackage(\"shop.v1\"),\n        rpc.WithValidation(true),\n    )\n    \n    // Register handlers\n    rpc.Register(svc, createOrder)  // Automatically registers as \"CreateOrder\"\n    \n    // Create handler\n    handler, _ := rpc.NewHandler(svc)\n    \n    // Create a standard mux\n    mux := http.NewServeMux()\n    \n    // Chain middleware: auth -\u003e logging -\u003e context -\u003e handler\n    // Context values flow through to RPC handlers\n    mux.Handle(\"/\", \n        authMiddleware(\n            loggingMiddleware(\n                contextMiddleware(handler))))\n    \n    // Add health check endpoint\n    mux.HandleFunc(\"/health\", func(w http.ResponseWriter, r *http.Request) {\n        w.WriteHeader(http.StatusOK)\n        fmt.Fprintln(w, `{\"status\":\"healthy\"}`)\n    })\n    \n    // Serve static files\n    mux.Handle(\"/static/\", http.StripPrefix(\"/static/\", \n        http.FileServer(http.Dir(\"./static\"))))\n    \n    // Add metrics endpoint\n    mux.Handle(\"/metrics\", promhttp.Handler())\n    \n    // Use with popular routers (e.g., gorilla/mux, chi)\n    // router := chi.NewRouter()\n    // router.Use(middleware.RequestID)\n    // router.Use(middleware.Logger)\n    // router.Mount(\"/api\", handler)\n    \n    // Wrap with h2c for HTTP/2 support\n    h2s := \u0026http2.Server{}\n    h2Handler := h2c.NewHandler(mux, h2s)\n    \n    log.Println(\"Server starting on :8080\")\n    log.Fatal(http.ListenAndServe(\":8080\", h2Handler))\n}\n```\n\nThis flexibility allows you to:\n- **Pass request-scoped data** (request ID, user info, trace ID) from middleware to handlers\n- **Add authentication, rate limiting, or CORS handling** at the HTTP layer\n- **Serve your RPC API alongside REST endpoints** on the same server\n- **Integrate with observability tools** (Prometheus, OpenTelemetry)\n- **Use popular Go web frameworks and routers** (chi, gin, echo, gorilla/mux)\n- **Implement custom request/response processing** with full HTTP control\n\nThe key insight is that Hyperway's handler is just a standard `http.Handler`, so any context values set via `r.WithContext()` in your middleware will be available in your RPC handlers via the `ctx` parameter.\n\n## 🏗️ Architecture\n\nHyperway implements a schema-driven architecture where:\n\n### Schema-First Philosophy\n- **Go Types as Schema Source**: Your structs define the contract, enforced at compile time\n- **Runtime Schema Generation**: Dynamic Protobuf generation maintains wire compatibility\n- **Single Source of Truth**: No schema duplication between `.proto` files and Go code\n\n### Technical Foundation\n- **High-Performance Parsing**: Leverages hyperpb for optimized message handling\n- **Multi-Protocol Gateway**: Unified implementation of gRPC, Connect, and gRPC-Web\n- **Standard http.Handler Interface**: Seamless integration with Go's HTTP ecosystem\n- **Extensible Middleware**: Interceptors for cross-cutting concerns\n- **Type-Safe by Design**: Compile-time type checking with runtime protocol compliance\n\n## 🔄 Hyperway vs Traditional Development\n\n### Development Workflow Comparison\n\n**Traditional Proto-First:**\n1. Edit `.proto` file\n2. Run code generation\n3. Update implementation\n4. Handle generated code inconsistencies\n\n**Hyperway:**\n1. Edit Go struct\n2. Run service\n3. (Optional) Export `.proto` when sharing\n\n### When to Export Protos\n\nExport `.proto` files when you need:\n- **Cross-language clients** - Generate SDKs for other languages\n- **API documentation** - Share contracts with external teams\n- **Breaking change detection** - Use with buf or similar tools\n- **Schema registries** - Upload to BSR or internal registries\n\n### Complementary Workflow\n\n```bash\n# Development phase: Iterate rapidly with Go types\n# Just write code, test, and refine\n\n# Collaboration phase: Export schemas for wider use\nhyperway proto export --endpoint localhost:8080 --output ./proto\n\n# Now you have both:\n# - Fast iteration for ongoing development\n# - Standard .proto files for tooling and cross-team collaboration\n```\n\n## 📈 When to Use Hyperway\n\n✅ **Perfect for:**\n- Teams embracing schema-driven development with Go\n- Microservices requiring both type safety and rapid iteration\n- Projects that value schema-first principles without manual schema maintenance\n- Services that need multi-protocol support (gRPC + Connect RPC)\n- Applications using all RPC types (unary, server/client/bidirectional streaming)\n- Systems requiring automatic validation and type safety\n- Organizations wanting to share schemas across polyglot teams\n\n❌ **Current Limitations:**\n- **Go-only service definitions** - Use exported protos for other languages\n- **Limited buf curl compatibility** - Some Well-Known Types (Struct, FieldMask) have JSON parsing issues with buf curl\n- **Map of Well-Known Types** - `map[string]*structpb.Value` causes runtime panics (implementation limitation)\n- **gRPC streaming compatibility** - All streaming types (server/client/bidirectional) work with standard gRPC and Connect clients\n\n## 🚀 Current Status\n\nHyperway supports all RPC types (unary, server-streaming, client-streaming, and bidirectional streaming) with:\n- ✅ Comprehensive test coverage\n- ✅ Performance optimizations\n- ✅ Memory-efficient implementation\n- ✅ Thread-safe design\n- ✅ Clean static analysis\n- ✅ Configurable streaming behavior\n\n### Tooling Integration\n- ✅ **Proto Export** - Generate standard `.proto` files from running services\n- ✅ **Full Compatibility** - Exported protos work with buf, protoc, and all standard tools\n- ✅ **Schema Registries** - Compatible with BSR and corporate registries\n- ✅ **Wire Compatibility** - Works with any gRPC/Connect client\n\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/i2y/hyperway.git\ncd hyperway\n\n# Install dependencies\ngo mod download\n\n# Run tests\nmake test\n\n# Run linter\nmake lint\n\n# Run benchmarks\nmake bench\n```\n\n## 📄 License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## 🗺️ Roadmap\n\n### Completed ✅\n- [x] Server-streaming RPC support\n- [x] Client-streaming RPC support\n- [x] Bidirectional streaming RPC support\n- [x] Streaming performance optimizations\n- [x] Protobuf Editions support (Edition 2023)\n- [x] Additional Well-Known Types (Struct, Value, ListValue, FieldMask)\n- [x] Buffer pooling and concurrency optimizations\n- [x] JSON-RPC 2.0 protocol support (v0.4.0)\n- [x] Multi-compression support: gzip, brotli, zstd (v0.5.0)\n- [x] Configurable message size limits (v0.5.0)\n- [x] Enhanced proto export with language-specific options (v0.5.0)\n- [x] Unified protocol configuration API (v0.6.0)\n\n### In Progress 🚧\n\n### Planned 📋\n- [ ] Metrics and tracing integration (OpenTelemetry)\n- [ ] WebSocket support for JSON-RPC\n- [ ] Plugin system for custom protocols\n\n## ❓ FAQ\n\n### Q: How does this work with existing proto tooling?\nA: Hyperway generates standard Protobuf schemas. Export them as `.proto` files and use any existing tooling - buf, protoc, linters, breaking change detection, etc. Your exported schemas are fully compatible with the entire Protobuf ecosystem.\n\n### Q: Is this suitable for production use?\nA: Hyperway is currently under active development but may be suitable for production use depending on your requirements. It supports all RPC types (unary, server-streaming, client-streaming, and bidirectional streaming) with competitive performance. We recommend thoroughly testing it for your specific use case before production deployment. It's particularly well-suited for prototyping, internal tools, and services where rapid development is prioritized.\n\n### Q: What about cross-language support?\nA: Export your schemas as `.proto` files and generate clients in any language. Hyperway maintains full wire compatibility with standard gRPC and Connect clients, so your services work seamlessly with clients written in any supported language.\n\n## 📚 API Reference\n\n### Service Creation\n```go\n// Create a new service\nsvc := rpc.NewService(name string, opts ...ServiceOption)\n\n// Service options\nrpc.WithPackage(pkg string)                    // Set protobuf package\nrpc.WithValidation(enabled bool)                // Enable validation\nrpc.WithReflection(enabled bool)                // Enable gRPC reflection\nrpc.WithMaxReceiveMessageSize(bytes int)        // Max receive size\nrpc.WithMaxSendMessageSize(bytes int)           // Max send size\nrpc.WithInterceptors(interceptors ...Interceptor) // Add interceptors\nrpc.WithServiceConfig(json string)              // gRPC service config\nrpc.WithEdition(edition string)                 // Protobuf edition\n```\n\n### Method Registration\n```go\n// Automatic name extraction\nrpc.Register(svc, handler)                      // Extract name from function\nrpc.RegisterServerStream(svc, handler)          // Server streaming\nrpc.RegisterClientStream(svc, handler)          // Client streaming\nrpc.RegisterBidiStream(svc, handler)            // Bidirectional streaming\n\n// Explicit naming\nrpc.RegisterAs(svc, name, handler)              // Unary with name\nrpc.RegisterServerStreamAs(svc, name, handler)  // Server stream with name\nrpc.RegisterClientStreamAs(svc, name, handler)  // Client stream with name\nrpc.RegisterBidiStreamAs(svc, name, handler)    // Bidi stream with name\n\n// Batch registration\nsvc.RegisterAll(methods ...MethodDefinition)    // Register multiple\nrpc.Unary(name, handler)                        // Unary method definition\nrpc.ServerStreamDef(name, handler)              // Server stream definition\nrpc.ClientStreamDef(name, handler)              // Client stream definition\nrpc.BidiStreamDef(name, handler)                // Bidi stream definition\n```\n\n### Protocol Configuration\n```go\n// Presets\nrpc.WithPreset(rpc.PresetREST)                  // Connect + JSON-RPC\nrpc.WithPreset(rpc.PresetGRPC)                  // gRPC + gRPC-Web\nrpc.WithPreset(rpc.PresetAll)                   // All protocols\nrpc.WithPreset(rpc.PresetMinimal)               // Connect only\n\n// Individual protocols\nrpc.WithConnect(allowJSON, allowProto bool)     // Enable Connect\nrpc.WithGRPC(enableReflection bool)             // Enable gRPC\nrpc.WithGRPCWeb()                                // Enable gRPC-Web\nrpc.WithJSONRPC(path string, batchLimit int)    // Enable JSON-RPC\n\n// Disable protocols\nrpc.DisableConnect()                            // Disable Connect\nrpc.DisableGRPC()                                // Disable gRPC\nrpc.DisableGRPCWeb()                            // Disable gRPC-Web\nrpc.DisableJSONRPC()                            // Disable JSON-RPC\n\n// Fluent builder\nrpc.ConfigureProtocols().\n    Connect(true, true).\n    GRPC(true).\n    Build()\n```\n\n### Error Handling\n```go\n// Error builders\nrpc.InvalidArgument(msg)                        // Create error builder\nrpc.NotFound(msg)                              // Common error types\nrpc.Internal(msg)                              // Internal error\nrpc.NewErrorBuilder()                          // Custom builder\n\n// Error builder methods\n.Code(code)                                    // Set error code\n.Message(msg)                                  // Set message\n.Messagef(format, args...)                    // Formatted message\n.Detail(key, value)                           // Add detail\n.Details(map[string]any)                      // Add multiple details\n.Build()                                       // Build error\n\n// Error collection\ncollector := rpc.NewErrorCollector()\ncollector.Add(field, message)                  // Add error\ncollector.Addf(field, format, args...)        // Add formatted\ncollector.HasErrors()                         // Check if has errors\ncollector.AsError()                           // Convert to error\n```\n\n### Context Manipulation\n```go\n// Context helper\nhelper := rpc.Context(ctx)\n\n// Headers and trailers\nhelper.SetHeader(key, value)                   // Set response header\nhelper.SetHeaders(map[string]string)          // Set multiple headers\nhelper.SetTrailer(key, value)                 // Set response trailer\nhelper.SetTrailers(map[string]string)         // Set multiple trailers\n\n// Get request data\nhelper.GetHeader(key)                         // Get request header\nhelper.GetMetadata(key)                       // Get request metadata\nhelper.RequireHeader(key, errorMsg)           // Require header\nhelper.Validate()                             // Validate requirements\n```\n\n### Handler Creation\n```go\n// Create HTTP handler from services\nhandler, err := rpc.NewHandler(services ...*Service)\n\n// Handler options\nrpc.WithGatewayOptions(opts ...gateway.Option)\n```\n\n## 🙏 Acknowledgments\n\n- [Connect-RPC](https://connectrpc.com) - Protocol specification and wire format\n- [hyperpb](https://github.com/bufbuild/hyperpb-go) - High-performance protobuf parsing with PGO\n- [go-playground/validator](https://github.com/go-playground/validator) - Struct validation\n- The Go community for inspiration and feedback\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fi2y%2Fhyperway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fi2y%2Fhyperway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fi2y%2Fhyperway/lists"}