GitHub - go-woo/protoc-gen-echo: Generate Echo backend code (original) (raw)

What is protoc-gen-echo?

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.

Quick start

Step 0: Pre-installation on ubuntu

sudo apt install protobuf-compiler make

Step 1: Edit ./example/v1/greeter.proto

service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {
    option (google.api.http) = {
      get: "/helloworld/{name}/hi/{nice}"
    };
  }
  //...
}
//...

Step 2: Generate

You can generate code used by make:

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 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>Y</mi><mi>o</mi><mi>u</mi><mi>r</mi><mi>S</mi><mi>e</mi><mi>r</mi><mi>v</mi><mi>i</mi><mi>c</mi><mi>e</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(YourService)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord mathnormal">o</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal">ce</span><span class="mclose">)</span></span></span></span>(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.

Step 3: Write example business logic

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.

Step 4: Run example

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

Step 5: Optional JWT support

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.

‼️ Special notes

Generate gRPC

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

Generate Open Api Spec document

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

Validate

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

Todo

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