protoc-gen-echo
is a protoc plug-in that generates Echo server code
from proto file.
If you want to create a Echo's http api
/helloworld/:name/hi/:nice
, you just need to add rpc in a proto file, and generate it.
/helloworld/:name/hi/:nice
mapping http api will be generated by protoc-gen-echo
.
protoc-gen-echo
can generate complete backend all code combination with protoc-gen-ent.
** About ent you can find more help from ent.
sudo apt install protobuf-compiler make
./example/v1/greeter.proto
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/helloworld/{name}/hi/{nice}"
};
}
//...
}
//...
You can generate code used by make
:
make example
Or you can generate code used by below too:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install github.com/go-woo/protoc-gen-echo@latest
protoc --proto_path=. \
--proto_path=./third_party \
--go_out=paths=source_relative:. \
--echo_out=paths=source_relative:. \
./example/v1/greeter.proto
The protoc-gen-echo
generated 2 files:greeter_router.pb.go
and greeter_handler.pb.go
.
The greeter.pb.go
was generated by protoc-gen-go
More help can be found in protoc.
Your business logic stubs has been generated in your_xxxx_handler.pb.go
,
You can edit business logic in stubs.
func $(YourService)$(RpcName)BusinessHandler(payload *YourRequest) (YourReply, error) {
// Here can put your business logic, can use ORM:github.com/go-woo/protoc-gen-ent
return YourReply{}, nil
}
All handlers typo can be found in your_xxxx_router.pb.go
.
For this example, in greeter_router.pb.go
.
You can find generated echo's handler _Greeter_SayHello0_HTTP_Handler
.
func RegisterGreeterRouter(e *echo.Echo) {
e.GET("/helloworld/:name/hi/:nice", _Greeter_SayHello0_HTTP_Handler)
//...
}
In same file, you can find _Greeter_SayHello0_HTTP_Handler
's implement:
func _Greeter_SayHello0_HTTP_Handler(c echo.Context) error {
var req *HelloRequest = new(HelloRequest)
req.Name = c.Param(strings.ToLower("Name"))
req.Nice = c.Param(strings.ToLower("Nice"))
reply, err := GreeterSayHelloBusinessHandler(req, c)
if err != nil {
return err
}
return c.JSON(http.StatusOK, &reply)
}
Our focus is on GreeterSayHelloBusinessHandler(payload)
.
In greeter_handler.pb.go
, you can write business logic.
func GreeterSayHelloBusinessHandler(req *HelloRequest, c echo.Context) (HelloReply, error) {
// Here can put your business logic,protoc-gen-ent soon coming
reqJson, err := json.Marshal(req)
if err != nil {
return HelloReply{}, err
}
fmt.Printf("Got HelloRequest is: %v\n", string(reqJson))
return HelloReply{}, nil
}
For running this example we need to write a main.go
package main
import (
v1 "github.com/go-woo/protoc-gen-echo/example/v1"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
v1.RegisterGreeterRouter(e)
// you can add custom router outside protoc-gen-echo too.
// MyCustomRouter(e)
e.Logger.Fatal(e.Start(":1323"))
}
More help and doc can be found on Echo , include rate limited, auto update TLS cert, etc.
cd example && go run main.go
Open browser, URL:http://localhost:1223/helloworld/Lok-Tar/hi/Ogar
Or shell execute
curl -X GET http://localhost:1323/helloworld/Lok-Tar/hi/Ogar
Service option
//get token URL
option (google.api.default_host) = "/login";
//need auth root path, can multi path
option (google.api.oauth_scopes) =
"/restricted,"
was used for JWT describer.
If you want to support JWT, can add it. Else you can comment it.
Do not remove your_xxxx_handler.pb.go
. It was generated only when the first time, and will not be generated or overwritten after that again, because the business logic code you added is already in it.
JSON format in http body. If http client request has body, header should has Content-Type: application/json
Validate. Single source(proto) is the most important means to ensure consistency. protobuf message filed validate can use protoc-gen-validate.
protoc-gen-echo
follow google.api.httprule.
ent still does not support message nesting, so proto http rule body must be *.
gRPC generated by protoc-gen-go-grpc
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Add --go-grpc_out=paths=source_relative:. \
protoc --proto_path=. \
--proto_path=./third_party \
--go_out=paths=source_relative:. \
--echo_out=paths=source_relative:. \
--go-grpc_out=paths=source_relative:. \
./example/v1/greeter.proto
OAS generated by protoc-gen-openapi
go install github.com/google/gnostic/cmd/protoc-gen-openapi@latest
Add --openapi_out=paths=source_relative:. \
protoc --proto_path=. \
--proto_path=./third_party \
--go_out=paths=source_relative:. \
--echo_out=paths=source_relative:. \
--openapi_out=paths=source_relative:. \
./example/v1/greeter.proto
Generated yaml file can be browser on swagger or openapi
Fields validate generated by protoc-gen-validate
go install github.com/envoyproxy/protoc-gen-validate@latest
Add --validate_out="lang=go:." \
protoc --proto_path=. \
--proto_path=./third_party \
--go_out=paths=source_relative:. \
--echo_out=paths=source_relative:. \
--validate_out="lang=go:." \
./example/v1/greeter.proto
https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#securitySchemeObject
https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto