Protomicro is a tool/generator/cli/scaffolding(?) to help developers build microserivces using Go, Grpc-Gateway, Protobuf & DI. Simple and fast.
To start using Protomicro
, download the Makefile
to a blank folder. Then run make or protomicro commands. (Suppose Go, make, docker and protoc has been installed in your enviroment. You $GOPATH has been set).
- Project layout - https://github.com/golang-standards/project-layout
- Dependency Injection - Wire integration
- gRPC Server / Gateway
- GRPC Middlewares (Rate Limit, Authentication Basic, Error, native)
- Gorm (MySQL, PostgreSQL, Sqlite), Mongo, Elasticsearch integration
- Protobuf & Faker integration
- Dockerfiles - Postgres, Mongo, Elasticsearch, RabbitMQ, Redis, Protomicro
- A sample microservice and test before creating generator (microshop)
- Define Hydra/Casbin/Keycloak/Auth0/Google Auth/Firebase Auth template for Module generator
- Module generator - generate API, Model, Controller, Register from proto files
- Sample CRUDS modules
- Kubenetes deployment
- Istio deployment
- OpenID OAuth2 Server (Hydra/Keycloak/Casbin)
- Casbin RBAC & Istio Mixer Adapter
https://github.com/gomaglev/microshop
make start
or use docker
make run
# sample - download default Makefile to microshop folder
cd ~
mkdir microshop
cd microshop
curl -OL https://github.com/gomaglev/protomicro/Makefile
# make protomicro cli (WIP, will change to public after v1 release)
# for contributors, create issues in this repo to get access to cli source code.
make cli
# code generation
./protomicro new microshop
./protomicro gen order/item/message
make protos
make wire
# start the service
make start
Only for fake data generation:
make faker
Change default values in the Makefile
to meet your requirement.
APP_NAME := microshop
CLI_NAME := protomicro
GO_VERSION := 1.15
make cli
will build a binary cli tool under your project folder.
${CLI_NAME} new ${YOUR_APP_NAME}
will create the structure.
├── api : Protobuf defination
├── cmd : Main programs
│ └── ${YOUR_APP_NAME}
│ └── main.go
├── internal
│ └── ${YOUR_APP_NAME}
│ ├── service : Business logic
│ ├── model : Database model
│ │ ├── gorm : Gorm model interface
│ │ │ ├─ entity : Gorm entity
│ │ │ └─ model : Gorm model implementation
│ │ ├── elastic : Elasticsearch model
│ │ ├── mongo : MongoDB model
│ │ └── external : External third party datasource
│ ├── dto : Data transfer object
│ ├── injector : Dependency Injection
│ ├── errors : Common errors
│ └── config : Config file reader
├── configs : Config files
├── deployments : k8s, istio related files
├── docs : Documentations
├── pkg
│ ├── authentication : Authentication (Login)
│ ├── authorization : Authorization (RBAC, Local)
│ ├── grpclimit : Rate limit
│ ├── icontext : Context with transaction
│ ├── server : gRPC server & gRPC gateway
│ └── util : Utilities
├── scripts : Shell scripts, runnable files
├── api
├── cmd
│ └── ${YOUR_APP_NAME}
│ └── main.go
├── configs
├── deployments
├── docs
├── internal
│ └── ${YOUR_APP_NAME}
│ ├── service
│ ├── model
│ │ ├── gorm
│ │ │ ├─ gorm.go
│ │ │ ├─ entity
│ │ │ │ └─ entity.go
│ │ │ └─ model
│ │ │ ├─ common.go
│ │ │ ├─ trans.go
│ │ │ └─ model.go
│ │ ├── elastic
│ │ ├── mongo
│ │ └── external
│ ├── dto
│ ├── injector
│ ├── errors
│ └── config
├── pkg
│ ├── authentication
│ ├── authorization
│ ├── grpclimit
│ ├── icontext
│ ├── server
│ └── util
├── scripts
├── tools.go
├── .travis.yml
├── Dockerfile
└── Makefile
${CLI_NAME} gen ${MODULE}
For example, protomicro gen order/item/message
protobuf, service, model, injector, dto and test files will be generated.
make protos
make faker
├── api: *.proto files for generation
│ └── order
│ ├── v1
│ │ └── order.proto
│ └── item
│ ├── v1
│ │ └── item.proto
│ └── message
│ └── v1
│ └── message.proto
└── internal
└── app
├── service: generated from *.proto in api folder
│ └── order
│ ├── v1
│ │ ├── order_grpc.pb.go
│ │ ├── order.pb.go
│ │ ├── order.pb.gw.go
│ │ ├── order.pb.validate.go
│ │ ├── order.svc.go
│ │ └── order_test.go
│ └── item
│ ├── v1
│ │ ├── item_grpc.pb.go
│ │ ├── item.pb.go
│ │ ├── item.pb.gw.go
│ │ ├── item.pb.validate.go
│ │ ├── item.svc.go
│ │ └── item_test.go
│ └── message
│ └── v1
│ ├── message_grpc.pb.go
│ ├── message.pb.go
│ ├── message.pb.gw.go
│ ├── message.pb.validate.go
│ ├── message.svc.go
│ └── message_test.go
├── model
│ ├── order.go
│ ├── order_item.go
│ ├── order_item_message.go
│ ├── gorm: default is gorm, if a model use other databases, implement them
│ │ │── entity
│ │ │ ├── order.go
│ │ │ ├── order_item.go
│ │ │ └── order_item_message.go
│ │ └── model
│ │ ├── order.go
│ │ ├── order_item.go
│ │ └── order_item_message.go
│ │── mongo: blank
│ │ │── entity
│ │ │ ├── order.go
│ │ │ ├── order_item.go
│ │ │ └── order_item_message.go
│ │ └── model
│ │ ├── order.go
│ │ ├── order_item.go
│ │ └── order_item_message.go
│ │── elastic: blank
│ │ │── entity
│ │ │ ├── order.go
│ │ │ ├── order_item.go
│ │ │ └── order_item_message.go
│ │ └── model
│ │ ├── order.go
│ │ ├── order_item.go
│ │ └── order_item_message.go
│ └── external: blank
│ │── entity
│ │ ├── order.go
│ │ ├── order_item.go
│ │ └── order_item_message.go
│ └── model
│ ├── order.go
│ ├── order_item.go
│ └── order_item_message.go
└── dto
├── order.go
├── order_item.go
└── order_item_message.go
curl --request GET --header \
"Authorization: Basic $(echo -n user:password | base64)" \
http://localhost:8888/status
High performance, Reliability, Scalability, Consistency are key points in building distributed systems. Compare to other languages, Golang can really make your life easier. After switched our systems from Java & Node.js to Golang, we can find very few reason to go back.
Milliseconds matter. gRPC uses HTTP/2 to support highly performant and scalable Handler's and makes use of binary data rather than just text which makes the communication more compact and more efficient.
Protobufs have a lot of good things going for them. They're easy to write, easy to understand, compile to a vast number of languages, and support custom generators for things like validation and help documentation. Their size over the wire is very small and they are designed to be backwards- and forwards-compatible. This makes them extremely attractive as a means of transferring data in a client/server architecture, or in a microservice environment.
It may also have some bad things
. I'm not going to give up using it because imo most of those bad things
are good
to build robust systems.
Protocol Buffers are not designed to handle large messages. As a general rule of thumb, if you are dealing in messages larger than a megabyte each, it may be time to consider an alternate strategy.
Project layout follows the standard below: https://github.com/golang-standards/project-layout
Use revive or other lint tools. (ID vs Id complains).