Bookstore
Bookstore
Section titled “Bookstore”The go-zero official bookstore example is the canonical starting point for multi-service development. It demonstrates how an HTTP API gateway delegates to a backend gRPC service, which reads and writes MySQL through a goctl-generated model.
Architecture
Section titled “Architecture”Client │ ▼ HTTP :8888bookstore-api (go-zero REST server) │ ▼ gRPC :8080bookstore-rpc (zrpc server) │ ▼ MySQLGet the Code
Section titled “Get the Code”git clone https://github.com/zeromicro/go-zero.gitcd go-zero/example/bookstoreDirectory layout:
bookstore/├── api/ # HTTP gateway│ ├── bookstore.go # entry point│ ├── etc/│ │ └── bookstore-api.yaml│ └── internal/│ ├── config/│ ├── handler/ # HTTP handlers (generated)│ ├── logic/ # business logic│ ├── svc/ # ServiceContext│ └── types/ # request/response structs├── rpc/ # gRPC backend│ ├── bookstore.go│ ├── etc/│ │ └── bookstore.yaml│ ├── internal/│ │ ├── config/│ │ ├── logic/ # gRPC handlers│ │ ├── model/ # MySQL model (generated)│ │ └── svc/│ └── pb/ # protobuf definitions└── shared/ # shared proto typesStep-by-Step Walkthrough
Section titled “Step-by-Step Walkthrough”1. Create the Database
Section titled “1. Create the Database”CREATE DATABASE bookstore;USE bookstore;
CREATE TABLE `book` ( `book` varchar(255) NOT NULL COMMENT 'book name', `price` int NOT NULL DEFAULT 0 COMMENT 'book price') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;2. Generate the MySQL Model
Section titled “2. Generate the MySQL Model”cd rpcgoctl model mysql ddl -src ./internal/model/book.sql -dir ./internal/model -cache3. Configure Services
Section titled “3. Configure Services”Name: bookstore.rpcListenOn: 0.0.0.0:8080
DataSource: root:password@tcp(127.0.0.1:3306)/bookstore?parseTime=trueCache: - Host: 127.0.0.1:6379Name: bookstore-apiHost: 0.0.0.0Port: 8888
Bookstore: Etcd: Hosts: - 127.0.0.1:2379 Key: bookstore.rpc4. ServiceContext — RPC Client Wiring
Section titled “4. ServiceContext — RPC Client Wiring”type ServiceContext struct { Config config.Config Bookstore bookstore.Bookstore // generated gRPC client stub}
func NewServiceContext(c config.Config) *ServiceContext { return &ServiceContext{ Config: c, Bookstore: bookstore.NewBookstore(zrpc.MustNewClient(c.Bookstore)), }}5. Start Services
Section titled “5. Start Services”# Terminal 1 — RPC backendcd rpc && go run bookstore.go -f etc/bookstore.yaml
# Terminal 2 — API gatewaycd api && go run bookstore.go -f etc/bookstore-api.yaml6. Test
Section titled “6. Test”# Add a bookcurl -X POST http://localhost:8888/add \ -H "Content-Type: application/json" \ -d '{"book":"The Go Programming Language","price":42}'# {"ok":true}
# Check stockcurl "http://localhost:8888/check?book=The+Go+Programming+Language"# {"found":true,"price":42}Key Concepts Demonstrated
Section titled “Key Concepts Demonstrated”| Concept | Location | Description |
|---|---|---|
| API definition | api/bookstore.api | REST routes using .api DSL |
| Proto definition | rpc/pb/bookstore.proto | gRPC service contracts |
| goctl model | rpc/internal/model/ | Type-safe MySQL access with cache |
| ServiceContext | api/internal/svc/ | Dependency injection container |
| RPC client | api/internal/logic/ | Calling gRPC backend from logic layer |
| etcd discovery | api/etc/bookstore-api.yaml | RPC target resolved via etcd |
Common goctl Commands Used
Section titled “Common goctl Commands Used”# Regenerate API gateway codecd api && goctl api go -api bookstore.api -dir .
# Regenerate gRPC server/client stubscd rpc && goctl rpc protoc pb/bookstore.proto \ --go_out=./pb --go-grpc_out=./pb --zrpc_out=.
# Regenerate model from DDLgoctl model mysql ddl -src ./internal/model/book.sql \ -dir ./internal/model -cache