Protocol & Codegen
Sphere follows a “protocol-first” approach where you define your APIs once in Protobuf and generate everything else from those definitions. This ensures consistency across your entire stack and reduces boilerplate code.
Core Philosophy
The fundamental principle is: Define once, generate everywhere.
Instead of writing HTTP handlers, request/response structs, validation code, and documentation separately, you:
- Define services and messages in
.proto
files - Annotate with HTTP mappings using
google.api.http
- Configure field binding with Sphere binding options
- Generate everything else using protoc plugins
This approach provides:
- Consistency: All layers use the same contracts
- Type Safety: Compile-time guarantees across the stack
- Documentation: API docs generated from source of truth
- Client SDKs: Automatically generated for multiple languages
- Reduced Boilerplate: No manual HTTP handler writing
Protocol as Contract
Single Source of Truth
Your .proto
files serve as the authoritative definition of:
- Data structures (messages)
- API operations (services and methods)
- Error conditions (enums with metadata)
- HTTP mapping (via annotations)
- Field constraints (via validation rules)
Code Generation Pipeline
Generator Chain
The code generation happens in a specific order:
- protoc-gen-go: Generate base Go types
- protoc-gen-sphere-binding: Add struct tags for binding
- protoc-gen-sphere: Generate HTTP handlers and routing
- protoc-gen-sphere-errors: Generate error types and handling
- protoc-gen-route: Generate custom routing (optional)
What Gets Generated
From your proto definitions, you automatically get:
Server-side Code
- Service interfaces to implement
- HTTP handlers with proper routing
- Request binding with validation
- Response marshaling with proper headers
- Error handling with consistent formatting
Client-side Code
- OpenAPI/Swagger documentation
- TypeScript SDKs (optional)
- Go client stubs (if needed)
- Validation schemas for frontend use
Developer Tools
- Interactive documentation via Swagger UI
- API testing endpoints
- Type definitions for IDE support
Benefits of This Approach
Type Safety
- Compile-time verification of API contracts
- No runtime surprises from mismatched types
- Automatic validation of required fields
- IDE support with autocomplete and error checking
Consistency
- Single source of truth for API definitions
- Consistent naming across all generated code
- Uniform error handling patterns
- Standardized HTTP response formats
Developer Experience
- Faster iteration cycles
- Less boilerplate code to maintain
- Clear separation of concerns
- Automatic documentation updates
Scalability
- Easy to add new services and methods
- Version management built-in
- Multiple output targets from one definition
- Team coordination through shared contracts
Protocol Organization
Recommended Structure
proto/
├── shared/v1/ # Common messages
│ ├── user.proto
│ └── common.proto
├── api/v1/ # Service definitions
│ ├── user_service.proto
│ └── auth_service.proto
└── errors/v1/ # Error definitions
├── user_errors.proto
└── common_errors.proto
Versioning Strategy
- Use explicit version packages (
v1
,v2
) - Keep shared types separate from services
- Plan for backwards compatibility
- Document breaking changes clearly
Evolution and Maintenance
Adding New Features
- Define new messages/services in
.proto
- Run code generation
- Implement service methods
- Tests and documentation are automatically updated
API Versioning
- Create new version packages for breaking changes
- Maintain multiple versions simultaneously
- Gradual migration paths for clients
- Automatic deprecation warnings
Team Collaboration
- Proto files as API contracts between teams
- Code review focuses on API design
- Generated code handles implementation details
- Consistent patterns across all services
Best Practices
Proto Design
- Clear naming: Use descriptive, consistent names
- Proper grouping: Organize by domain and version
- Forward compatibility: Design for future evolution
- Documentation: Comment services, methods, and fields
Code Generation
- Frequent regeneration: Update generated code early and often
- Don’t edit generated files: All changes go in
.proto
files - Version control: Commit both
.proto
and generated files - Automation: Integrate generation into build process
Error Handling
- Comprehensive coverage: Define errors for all failure modes
- Appropriate status codes: Use correct HTTP status codes
- Clear messages: Write user-friendly error messages
- Structured data: Include relevant context in errors
Last updated on