hyperway

module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2025 License: MIT

README ΒΆ

Hyperway

Build gRPC/Connect services in Go without writing a single .proto file.

Hyperway is an RPC framework that implements the Connect-RPC and gRPC protocols while letting you define your API using Go structs. It eliminates the need for protobuf files while maintaining wire compatibility with standard gRPC and Connect clients for unary RPCs. Under the hood, it leverages hyperpb for optimized dynamic protobuf parsing with performance comparable to generated code.

πŸš€ Why Hyperway?

The Traditional Approach

Traditional gRPC/Connect development follows a schema-first approach:

  1. Writing .proto files
  2. Running protoc with various plugins
  3. Managing generated code
  4. Rebuilding when schemas change

While 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.

The Hyperway Approach

Hyperway enables true schema-first development without manual .proto files:

  1. Define your API using Go structs
  2. Run your service
  3. Export .proto files automatically from the running service
  4. Share the schema with other teams from day one

This approach combines the benefits of schema-first development (early API contracts, cross-language support) with the convenience of working directly in Go. You can distribute .proto files to other teams immediately, enabling parallel development across different languages and platforms.

How It Works

Hyperway implements gRPC and Connect RPC protocols with dynamic capabilities:

  • Generates Protobuf schemas from your Go structs at runtime
  • Supports gRPC (Protobuf) and Connect RPC (both Protobuf and JSON)
  • Maintains wire compatibility with standard gRPC/Connect clients
  • Supports unary RPCs with full protocol compliance

πŸ“Š Performance

Hyperway is designed with performance in mind:

  • Comparable performance to traditional protoc-generated code
  • Minimal overhead from dynamic schema generation
  • Optimized memory usage with object pooling
  • Efficient message parsing using hyperpb

For detailed benchmarks and performance characteristics, see the benchmark directory.

✨ Features

  • 🚫 No Proto Files: Define your API using Go structs
  • ⚑ Optimized Performance: Uses hyperpb for efficient dynamic protobuf parsing
  • πŸ”„ Multi-Protocol: Supports gRPC (Protobuf) and Connect RPC (Protobuf and JSON)
  • βœ… Built-in Validation: Struct tags for input validation
  • πŸ” gRPC Reflection: Service discovery without proto files
  • πŸ“š OpenAPI Generation: Automatic API documentation
  • πŸ›‘οΈ Type-Safe: Full Go type safety without code generation
  • πŸ“€ Proto Export: Generate .proto files from your running service
  • 🀝 Protocol Compatible: Works with any gRPC or Connect client
  • πŸ—œοΈ Compression: Built-in gzip compression for both gRPC and Connect
  • ⏰ Well-Known Types: Automatic time.Time β†’ google.protobuf.Timestamp conversion
  • πŸ”Œ Custom Interceptors: Middleware for logging, auth, metrics, etc.
  • πŸ“¦ Proto3 Optional: Full support for optional fields
  • 🎯 Protobuf Editions: Support for Edition 2023 with features configuration

πŸ“¦ Installation

# Library
go get github.com/i2y/hyperway

# CLI tool
go install github.com/i2y/hyperway/cmd/hyperway@latest

🎯 Quick Start

package main

import (
    "context"
    "log"
    "net/http"
    
    "github.com/i2y/hyperway/rpc"
)

// Define your API using Go structs
type CreateUserRequest struct {
    Name  string `json:"name" validate:"required,min=3"`
    Email string `json:"email" validate:"required,email"`
}

type CreateUserResponse struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

// Write your business logic
func createUser(ctx context.Context, req *CreateUserRequest) (*CreateUserResponse, error) {
    // Your business logic here
    return &CreateUserResponse{
        ID:   "user-123",
        Name: req.Name,
    }, nil
}

func main() {
    // Create a service
    svc := rpc.NewService("UserService", 
        rpc.WithPackage("user.v1"),
        rpc.WithValidation(true),
    )
    
    // Register your handlers
    if err := rpc.Register(svc, "CreateUser", createUser); err != nil {
        log.Fatal(err)
    }
    
    // Start serving (supports gRPC and Connect RPC protocols)
    gateway, _ := rpc.NewGateway(svc)
    log.Fatal(http.ListenAndServe(":8080", gateway))
}

πŸ§ͺ Testing Your Service

Your service automatically supports multiple protocols:

Connect RPC (JSON format)
curl -X POST http://localhost:8080/user.v1.UserService/CreateUser \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice","email":"alice@example.com"}'
gRPC (with reflection)
grpcurl -plaintext -d '{"name":"Bob","email":"bob@example.com"}' \
  localhost:8080 user.v1.UserService/CreateUser
Connect Protocol (JSON)
curl -X POST http://localhost:8080/user.v1.UserService/CreateUser \
  -H "Content-Type: application/json" \
  -H "Connect-Protocol-Version: 1" \
  -d '{"name":"Charlie","email":"charlie@example.com"}'
Connect Protocol (Protobuf)
# Using buf curl for Connect protocol testing
buf curl --protocol connect \
  --http2-prior-knowledge \
  --data '{"name":"David","email":"david@example.com"}' \
  http://localhost:8080/user.v1.UserService/CreateUser

πŸ”„ Best of Both Worlds: Code-First and Schema-First

Hyperway enables a unique hybrid approach:

1. Start with Code (No .proto files)
type User struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}
2. Export Proto When Needed
# Generate .proto files from your running service
hyperway proto export --endpoint localhost:8080 --output ./proto
3. Share With Other Teams

Now you have standard .proto files for:

  • Client SDK generation
  • Cross-language support
  • API documentation
  • Schema versioning

This approach gives you rapid development with Go while maintaining full protobuf compatibility.

πŸ› οΈ CLI Tool

# Export proto files from a running service
hyperway proto export --endpoint http://localhost:8080 --output ./proto

# Export as ZIP archive
hyperway proto export --endpoint http://localhost:8080 --format zip --output api.zip

πŸ“š Advanced Usage

Complex Types

Hyperway supports all Go types you need:

type Order struct {
    ID        string                 `json:"id"`
    Items     []OrderItem           `json:"items"`
    Metadata  map[string]string     `json:"metadata"`
    Customer  *Customer             `json:"customer,omitempty"`
    Status    OrderStatus           `json:"status"`
    CreatedAt time.Time             `json:"created_at"`
}
Validation

Use struct tags for automatic validation:

type RegisterRequest struct {
    Username string `json:"username" validate:"required,alphanum,min=3,max=20"`
    Password string `json:"password" validate:"required,min=8,containsany=!@#$%"`
    Email    string `json:"email" validate:"required,email"`
    Age      int    `json:"age" validate:"required,min=13,max=120"`
}
Real-World Example

Here's a more complete example showing various features:

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "time"
    
    "github.com/i2y/hyperway/rpc"
)

// Domain models with validation and well-known types
type CreatePostRequest struct {
    Title     string    `json:"title" validate:"required,min=5,max=200"`
    Content   string    `json:"content" validate:"required,min=10"`
    AuthorID  string    `json:"author_id" validate:"required,uuid"`
    Tags      []string  `json:"tags" validate:"max=10,dive,min=2,max=20"`
    Published bool      `json:"published"`
    Metadata  map[string]string `json:"metadata,omitempty"`
}

type Post struct {
    ID          string            `json:"id"`
    Title       string            `json:"title"`
    Content     string            `json:"content"`
    AuthorID    string            `json:"author_id"`
    Tags        []string          `json:"tags"`
    Published   bool              `json:"published"`
    PublishedAt *time.Time        `json:"published_at,omitempty"` // Optional timestamp
    CreatedAt   time.Time         `json:"created_at"`             // Required timestamp
    UpdatedAt   time.Time         `json:"updated_at"`
    TTL         *time.Duration    `json:"ttl,omitempty"`          // Optional duration
    Metadata    map[string]string `json:"metadata"`
}

// Service implementation
type BlogService struct {
    // your database, cache, etc.
}

func (s *BlogService) CreatePost(ctx context.Context, req *CreatePostRequest) (*Post, error) {
    // Business logic here
    now := time.Now()
    post := &Post{
        ID:        generateID(),
        Title:     req.Title,
        Content:   req.Content,
        AuthorID:  req.AuthorID,
        Tags:      req.Tags,
        Published: req.Published,
        CreatedAt: now,
        UpdatedAt: now,
        Metadata:  req.Metadata,
    }
    
    if req.Published {
        post.PublishedAt = &now
        ttl := 30 * 24 * time.Hour // 30 days
        post.TTL = &ttl
    }
    
    // Save to database...
    
    return post, nil
}

func main() {
    // Create blog service
    blogService := &BlogService{}
    
    // Create RPC service with interceptors
    svc := rpc.NewService("BlogService",
        rpc.WithPackage("blog.v1"),
        rpc.WithValidation(true),
        rpc.WithReflection(true),
        rpc.WithInterceptor(&rpc.RecoveryInterceptor{}),
        rpc.WithInterceptor(&rpc.TimeoutInterceptor{Timeout: 30*time.Second}),
    )
    
    // Register methods - no need to specify types!
    if err := rpc.Register(svc, "CreatePost", blogService.CreatePost); err != nil {
        log.Fatal(err)
    }
    
    // Create gateway and serve
    gateway, err := rpc.NewGateway(svc)
    if err != nil {
        log.Fatal(err)
    }
    
    log.Println("Blog service running on :8080")
    log.Println("- Connect RPC: POST http://localhost:8080/blog.v1.BlogService/CreatePost")
    log.Println("- gRPC: localhost:8080 (with reflection)")
    log.Fatal(http.ListenAndServe(":8080", gateway))
}
Multiple Services
// Create multiple services
userSvc := rpc.NewService("UserService", rpc.WithPackage("api.v1"))
authSvc := rpc.NewService("AuthService", rpc.WithPackage("api.v1"))
adminSvc := rpc.NewService("AdminService", rpc.WithPackage("api.v1"))

// Register handlers
rpc.Register(userSvc, "CreateUser", createUser)
rpc.Register(userSvc, "GetUser", getUser)
rpc.Register(authSvc, "Login", login)
rpc.Register(adminSvc, "DeleteUser", deleteUser)

// Serve all services on one port
gateway, _ := rpc.NewGateway(userSvc, authSvc, adminSvc)
Advanced Registration (Optional)

For more control, you can use the builder pattern:

// Use the builder pattern for additional options
rpc.MustRegisterMethod(svc,
    rpc.NewMethod("CreateUser", createUser).
        Validate(true).
        WithInterceptors(customInterceptor),
)
Interceptors/Middleware
// Add logging, auth, rate limiting, etc.
svc := rpc.NewService("MyService",
    rpc.WithInterceptor(&rpc.LoggingInterceptor{}),
    rpc.WithInterceptor(&rpc.RecoveryInterceptor{}),
)

πŸ—οΈ Architecture

Hyperway provides:

  • Dynamic Schema Generation: Converts Go types to Protobuf at runtime
  • Efficient Message Handling: Uses hyperpb for optimized parsing
  • Multi-Protocol Support: Implements both gRPC and Connect RPC protocols
  • Extensible Design: Custom interceptors, codecs, and compressors
  • Type Safety: Full Go type safety without code generation

πŸ“ˆ When to Use Hyperway

βœ… Perfect for:

  • Rapid prototyping and development
  • Microservices that need quick iteration
  • Teams who prefer Go-first development
  • Projects where schema flexibility is important
  • Services that need multi-protocol support (gRPC + Connect RPC)
  • Applications using unary RPCs
  • Services that benefit from automatic validation

❌ Current Limitations:

  • No streaming support - Only unary RPCs are supported
  • Go-only service definitions - Use exported protos for other languages
  • Limited Well-Known Types - Currently supports Timestamp, Duration, Empty, Any
  • No gRPC-Web support - Use Connect protocol for browser clients

πŸš€ Production Readiness

Status: Production-Ready for Unary RPCs

Hyperway is production-ready for services using unary RPCs with the following assurances:

  • βœ… Comprehensive test coverage
  • βœ… Battle-tested protocol compliance
  • βœ… Performance optimized with benchmarks
  • βœ… Memory-efficient with pooling
  • βœ… Thread-safe implementation
  • βœ… Clean static analysis (passes all linters)

For streaming RPCs, use traditional gRPC with .proto files until streaming support is added.

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup
# Clone the repository
git clone https://github.com/i2y/hyperway.git
cd hyperway

# Install dependencies
go mod download

# Run tests
make test

# Run linter
make lint

# Run benchmarks
make bench

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ—ΊοΈ Roadmap

  • Streaming RPC support (server-streaming, client-streaming, bidirectional)
  • Additional Well-Known Types (Any, Struct, Value, etc.)
  • Client library for type-safe RPC calls
  • Metrics and tracing integration (OpenTelemetry)
  • More compression algorithms (br, zstd)
  • Plugin system for custom protocols
  • Protobuf Editions support (Edition 2023)

πŸ™ Acknowledgments


Made with ❀️ by the Hyperway team

Directories ΒΆ

Path Synopsis
cmd
hyperway command
Package main provides the hyperway CLI tool for managing proto files and services.
Package main provides the hyperway CLI tool for managing proto files and services.
hyperway/commands
Package commands implements CLI commands for hyperway.
Package commands implements CLI commands for hyperway.
Package codec provides high-performance encoding/decoding using hyperpb.
Package codec provides high-performance encoding/decoding using hyperpb.
examples
basic command
comments command
Package main demonstrates how to add comments to proto exports.
Package main demonstrates how to add comments to proto exports.
editions command
Package main demonstrates how to use Protobuf Editions with hyperway.
Package main demonstrates how to use Protobuf Editions with hyperway.
export-proto command
Package main demonstrates how to export proto files from hyperway services.
Package main demonstrates how to export proto files from hyperway services.
grpc command
Package main demonstrates full gRPC protocol support with grpcurl compatibility.
Package main demonstrates full gRPC protocol support with grpcurl compatibility.
keepalive_retry command
Package main demonstrates gRPC keepalive and retry mechanisms.
Package main demonstrates gRPC keepalive and retry mechanisms.
multiprotocol command
Package main demonstrates multi-protocol support on the same port.
Package main demonstrates multi-protocol support on the same port.
pgo command
Package main demonstrates Profile-Guided Optimization (PGO) with hyperway.
Package main demonstrates Profile-Guided Optimization (PGO) with hyperway.
Package gateway provides multi-protocol support for gRPC and Connect RPC.
Package gateway provides multi-protocol support for gRPC and Connect RPC.
internal
proto
Package proto provides internal protobuf compilation utilities.
Package proto provides internal protobuf compilation utilities.
reflect
Package reflect provides reflection-based conversion utilities.
Package reflect provides reflection-based conversion utilities.
Package proto provides proto file export functionality.
Package proto provides proto file export functionality.
Package rpc provides error codes and handling for Connect/gRPC protocols.
Package rpc provides error codes and handling for Connect/gRPC protocols.
Package schema provides functionality to convert Go types to Protobuf FileDescriptorSet.
Package schema provides functionality to convert Go types to Protobuf FileDescriptorSet.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL