Overview
This guide covers creating new Protocol Buffer definitions for adding services to the microservices-app architecture.Proto File Structure
Follow this structure when creating new proto files:greeter service:
Creating a Proto File
Step 1: Create Directory Structure
Step 2: Write Proto Definition
Createproto/myservice/v1/myservice.proto:
Step 3: Validate Proto File
Run buf lint to check for style issues:Step 4: Generate Code
Generate Go and TypeScript code:services/gen/go/myservice/v1/myservice.pb.goservices/gen/go/myservice/v1/myserviceconnect/myservice.connect.gofrontend/src/gen/myservice/v1/myservice_pb.tsfrontend/src/gen/myservice/v1/myservice-MyService_connectquery.ts
Real Service Examples
Example 1: Greeter Service
Simple greeting service with a single RPC method:- Package:
greeter.v1(lowercase, versioned) - Service:
GreeterService(PascalCase with “Service” suffix) - RPC method:
Greet(PascalCase verb) - Messages:
GreetRequest/GreetResponse(PascalCase with Request/Response suffix) - Fields:
name,message(snake_case) - Field numbers: Sequential starting from 1
Example 2: Gateway Service
Service for invoking custom endpoints:Example 3: Caller Service
Service for making external HTTP requests:Naming Conventions
Package Names
- Format:
<service>.v1 - Case: lowercase
- Example:
greeter.v1,gateway.v1
Service Names
- Format:
<ServiceName>Service - Case: PascalCase
- Suffix: Always end with “Service”
- Example:
GreeterService,GatewayService
RPC Method Names
- Case: PascalCase
- Style: Verb or verb phrase
- Examples:
Greet,InvokeCustom,CallExternal
Message Names
- Format:
<MethodName>Request/<MethodName>Response - Case: PascalCase
- Example:
GreetRequest,GreetResponse
Field Names
- Case: snake_case
- Examples:
name,status_code,body_length
Go Package Option
Thego_package option must follow this format:
greeter.v1→github.com/.../greeter/v1;greeterv1gateway.v1→github.com/.../gateway/v1;gatewayv1caller.v1→github.com/.../caller/v1;callerv1
Field Numbering
Field numbers are permanent identifiers for serialization:Rules
- Start at
1(not0) - Must be unique within a message
- Numbers 1-15 use 1 byte encoding (use for frequent fields)
- Numbers 16-2047 use 2 bytes
- Never reuse field numbers (breaks backward compatibility)
- Reserve deleted field numbers:
Advanced Patterns
Nested Messages
Define messages within other messages:Repeated Fields
Represent lists or arrays:Enums
Define enumerated types:Optional Fields
In proto3, useoptional for nullable fields:
Timestamps
Use well-known types from google.protobuf:Integrating with Go Services
After generating code, implement the service in Go:Using in TypeScript Frontend
Generated React Query hooks provide type-safe API access:Testing Proto Changes
1. Lint Check
2. Breaking Change Detection
3. Code Generation
4. Build Services
5. Build Frontend
Common Issues
Lint Failures
Problem:buf lint reports style violations
Solution: Follow naming conventions:
- Package: lowercase with version (
myservice.v1) - Service: PascalCase with “Service” suffix
- RPC: PascalCase verb
- Messages: PascalCase with Request/Response suffix
- Fields: snake_case
Import Errors in Go
Problem: Go can’t find generated packages Solution: Checkgo_package option matches:
TypeScript Type Errors
Problem: Frontend shows type errors after proto changes Solution: Regenerate code and rebuild:Next Steps
- Code Generation - Learn about the code generation process
- Overview - Return to Protocol Buffers overview