Tonica CLI
Tonica includes a command-line tool to help you quickly scaffold projects and generate boilerplate code from Protocol Buffers.
Installation
Install the Tonica CLI tool:
go install github.com/tonica-go/tonica@latest
Make sure $GOPATH/bin is in your PATH.
Prerequisites
Before using the CLI, install the required tools:
# Install buf (Protocol Buffer tool)
brew install buf
# Install protoc plugins
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
Commands
tonica init
Initialize a new Tonica project with boilerplate structure.
Usage:
tonica init --name=PROJECT_NAME
Options:
--name(required) - Name of your project
Example:
mkdir myservice && cd myservice
tonica init --name=myservice
What it creates:
myservice/
├── cmd/
│ └── server/
│ └── main.go # Application entrypoint
├── internal/
│ └── service/ # Service implementations
├── proto/ # Protocol buffer definitions
│ └── myservice/
│ └── v1/
│ └── myservice.proto
├── buf.gen.yaml # Buf configuration
├── buf.yaml # Buf workspace
├── go.mod
└── README.md
tonica proto
Generate Protocol Buffer code and boilerplate for a new service.
Usage:
tonica proto --name=SERVICE_NAME
Options:
--name(required) - Name of the service
Example:
tonica proto --name=userservice
What it generates:
.protofile with basic service definition- gRPC service interface
- Gateway registration code
- OpenAPI specification
- Helper constants (ServiceName, ServiceAddrEnvName)
Generated files:
proto/
└── userservice/
└── v1/
├── userservice.proto # Proto definition
├── userservice.pb.go # Generated protobuf
├── userservice_grpc.pb.go # Generated gRPC server/client
├── userservice.pb.gw.go # Generated gateway
├── userservice_grpc.go # Tonica wrapper with helpers
└── userservice.swagger.json # OpenAPI spec
wrap (Advanced)
Generate Tonica wrapper code from existing .proto files. This is useful when you have existing proto definitions.
Usage:
go run ./pkg/tonica/cmd/wrap --proto path/to/service.proto
Options:
--proto(required) - Path to the.protofile
Example:
go run ./pkg/tonica/cmd/wrap --proto proto/payment/v1/payment.proto
What it generates:
Adds a *_grpc.go file with helper functions and constants:
ServiceName- Service name constantServiceAddrEnvName- Environment variable name for service address- Registration helpers
Quick Start Workflow
Here's a complete workflow for creating a new service:
# 1. Create project directory
mkdir myservice && cd myservice
# 2. Initialize Tonica project
tonica init --name=myservice
# 3. Generate your first service
tonica proto --name=myservice
# 4. Initialize Go module
go mod init github.com/yourusername/myservice
go mod tidy
# 5. Run the service
go run ./cmd/server
# 6. Test it
curl http://localhost:8080/docs
Proto File Example
When you run tonica proto --name=userservice, it generates a proto file like this:
syntax = "proto3";
package userservice.v1;
import "google/api/annotations.proto";
option go_package = "github.com/yourorg/myservice/proto/userservice/v1;userservicev1";
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse) {
option (google.api.http) = {
get: "/v1/users/{id}"
};
}
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) {
option (google.api.http) = {
post: "/v1/users"
body: "*"
};
}
}
message GetUserRequest {
string id = 1;
}
message GetUserResponse {
string id = 1;
string name = 2;
string email = 3;
}
message CreateUserRequest {
string name = 1;
string email = 2;
}
message CreateUserResponse {
string id = 1;
string name = 2;
string email = 3;
}
Generated Helper Constants
The *_grpc.go wrapper file includes useful constants:
package userservicev1
const (
// ServiceName is the name of the service for registration
ServiceName = "userservice-service"
// ServiceAddrEnvName is the environment variable name for the service address
ServiceAddrEnvName = "USERSERVICE_SERVICE_ADDR"
)
// RegisterGRPC registers the gRPC service
func RegisterGRPC(server *grpc.Server, impl UserServiceServer) {
RegisterUserServiceServer(server, impl)
}
// RegisterGateway registers the HTTP gateway
func RegisterGateway(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterUserServiceHandler(ctx, mux, conn)
}
Working with Existing Protos
If you have existing .proto files:
-
Option 1: Use
buf generatebuf generate -
Option 2: Generate Tonica wrappers
go run ./pkg/tonica/cmd/wrap --proto proto/myservice/v1/myservice.proto -
Option 3: Manual setup
- Run protoc with the required plugins
- Create wrapper functions manually
Buf Configuration
Tonica projects use buf for proto management. The generated buf.gen.yaml:
version: v1
managed:
enabled: true
plugins:
- plugin: buf.build/protocolbuffers/go
out: .
opt: paths=source_relative
- plugin: buf.build/grpc/go
out: .
opt: paths=source_relative
- plugin: buf.build/grpc-ecosystem/gateway
out: .
opt:
- paths=source_relative
- generate_unbound_methods=true
- plugin: buf.build/grpc-ecosystem/openapiv2
out: openapi
Regenerating Code
After modifying .proto files, regenerate code:
# Using buf (recommended)
buf generate
# Or using protoc directly
protoc --go_out=. --go-grpc_out=. --grpc-gateway_out=. \
--openapiv2_out=openapi \
proto/myservice/v1/*.proto
Troubleshooting
Command not found: tonica
Make sure $GOPATH/bin is in your PATH:
export PATH=$PATH:$(go env GOPATH)/bin
Protoc plugins not found
Install all required plugins:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
Import errors in generated code
Run go mod tidy to download dependencies:
go mod tidy
Buf errors
Ensure buf.yaml and buf.gen.yaml are properly configured. Check the Buf documentation for details.
Next Steps
- Getting Started - Build your first service
- Architecture - Understand the framework
- Configuration - Configure your services
- Best Practices - Production patterns