Skip to content

Commit

Permalink
Merge pull request #22 from nametake/add-original-interface
Browse files Browse the repository at this point in the history
Changed to generate original interface
  • Loading branch information
nametake authored Aug 30, 2020
2 parents d568e67 + deca581 commit 69e743c
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 83 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ install:
gen_examples: install
@protoc --go_out=plugins=grpc:./_examples/ --gohttp_out=./_examples/ --go_opt=paths=source_relative -I_examples ./_examples/*.proto

gen_pb:
@protoc --go_out=plugins=grpc:./testdata/ --gohttp_out=./testdata/ --go_opt=paths=source_relative -I testdata ./testdata/**/*.proto

test:
@go test ./... ./_examples/

test_gen:
@go test ./...

test_examples:
@go test ./_examples/

Expand Down
67 changes: 37 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
protoc-gen-gohttp
=================
# protoc-gen-gohttp

[![CircleCI](https://circleci.com/gh/nametake/protoc-gen-gohttp.svg?style=svg)](https://circleci.com/gh/nametake/protoc-gen-gohttp)

protoc-gen-gohttp is a plugin for converting Server's interface generated by protoc-gen-go's gRPC plugin to http.Handler.
protoc-gen-gohttp is a plugin of protoc that for using a `service` of Protocol Buffers as http.Handler definition.

In addition to this plugin, you need the protoc command, the proto-gen-go plugin and Google gRPC package.
The generated interface is compatible with the interface generated by the gRPC plugin.

In addition to this plugin, you need the protoc command and the proto-gen-go plugin.

The code generated by this plugin imports only the standard library, `github.com/golang/protobuf` and `google.golang.org/grpc`.

The converted http.Handler checks Content-Type Header, and changes Marshal/Unmarshal packages. The correspondence table is as follows.

| Content-Type | package |
|------------------------|-----------------------------------|
| ---------------------- | --------------------------------- |
| application/json | github.com/golang/protobuf/jsonpb |
| application/protobuf | github.com/golang/protobuf/proto |
| application/x-protobuf | github.com/golang/protobuf/proto |

Install
-------
## Install

```console
go get -u github.com/nametake/protoc-gen-gohttp
Expand All @@ -29,24 +29,22 @@ And install dependent tools. (e.g. macOS)
```console
brew install protobuf
go get -u github.com/golang/protobuf/protoc-gen-go
go get -u google.golang.org/grpc
```

How to use
----------
## How to use

```console
protoc --go_out=plugins=grpc:. --gohttp_out=. *.proto
protoc --go_out=. --gohttp_out=. *.proto
```

Example
-------
## Example

### Run

You can execute examples with the following command.

```console
make gen_examples
make run_examples
```

Expand Down Expand Up @@ -152,6 +150,18 @@ func restPath(service, method string, hf http.HandlerFunc) (string, http.Handler
}
```

#### Generated interface

protoc-gen-gohttp generates the following interface.

```go
type GreeterHTTPService interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}
```

This interface is compatible with the interface generated by gRPC plugin.

#### HTTPRule

protoc-gen-gohttp supports [google.api.HttpRule](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#httprule) option.
Expand Down Expand Up @@ -223,8 +233,7 @@ When you actually execute the above server and execute `curl -H "Content-Type: a
}
```

HTTP Handle Callback
--------------------
## HTTP Handle Callback

A http handle callback is a function to handle RPC calls with HTTP.

Expand All @@ -235,7 +244,7 @@ The callback is passed HTTP context and http.ResponseWriter and http.Request, RP
RPC arguments and return values, and errors may be nil. Here's when nil is passed:

| Timing | RPC argument | RPC return value | error |
|-----------------------------------------|--------------|------------------|-------|
| --------------------------------------- | ------------ | ---------------- | ----- |
| When an error occurs before calling RPC | nil | nil | err |
| When RPC returns an error | arg | nil | err |
| When an error occurs after calling RPC | arg | ret | err |
Expand All @@ -245,8 +254,7 @@ You **MUST HANDLE ERROR** in the callback. If you do not handle it, the error is

If nil is passed to the callback, the error is always handled as an InternalServerError.

grpc.UnaryServerInterceptor
---------------------------
## grpc.UnaryServerInterceptor

The convert method can receive multiple [grpc.UnaryServerInterceptor](https://godoc.org/google.golang.org/grpc#UnaryServerInterceptor).

Expand Down Expand Up @@ -280,18 +288,17 @@ If you passed interceptors, you must call handler to return the correct return t

If interceptors return the return value that is not expected by the RPC, http.Handler will pass an error like the following to the http handle callback and exit.

```
```console
/helloworld.Greeter/SayHello: interceptors have not return HelloReply
```

NOT SUPPORTED
-------------

- Streaming API
- Not create a convert method.
- HttpRule field below
- [selector](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule.FIELDS.string.google.api.HttpRule.selector)
- [additional_bindings](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule.FIELDS.repeated.google.api.HttpRule.google.api.HttpRule.additional_bindings)
- [custom](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule.FIELDS.google.api.CustomHttpPattern.google.api.HttpRule.custom)
- `enum` type query string
- `map` type query string
## NOT SUPPORTED

- Streaming API
- Not create a convert method.
- HttpRule field below
- [selector](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule.FIELDS.string.google.api.HttpRule.selector)
- [additional_bindings](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule.FIELDS.repeated.google.api.HttpRule.google.api.HttpRule.additional_bindings)
- [custom](https://cloud.google.com/endpoints/docs/grpc-service-config/reference/rpc/google.api#google.api.HttpRule.FIELDS.google.api.CustomHttpPattern.google.api.HttpRule.custom)
- `enum` type query string
- `map` type query string
15 changes: 10 additions & 5 deletions _examples/all_pattern.http.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions _examples/greeter.http.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 16 additions & 9 deletions _examples/httprule.http.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 15 additions & 5 deletions template.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,29 @@ import (
"google.golang.org/grpc/status"
)
{{ range $i, $service := .Services }}
// {{ $service.Name }}HTTPConverter has a function to convert {{ $service.Name }}Server interface to http.HandlerFunc.
// {{ $service.Name }}HTTPService is the server API for {{ $service.Name }} service.
type {{ $service.Name }}HTTPService interface {
{{ range $j, $method := $service.Methods -}}
{{ if ne $method.Comment "" -}}
// {{ $method.Comment }}
{{ end -}}
{{ $method.Name }}(context.Context, *{{ $method.Arg }}) (*{{ $method.Ret }}, error)
{{ end -}}
}
// {{ $service.Name }}HTTPConverter has a function to convert {{ $service.Name }}HTTPService interface to http.HandlerFunc.
type {{ $service.Name }}HTTPConverter struct {
srv {{ $service.Name }}Server
srv {{ $service.Name }}HTTPService
}
// New{{ $service.Name }}HTTPConverter returns {{ $service.Name }}HTTPConverter.
func New{{ $service.Name }}HTTPConverter(srv {{ $service.Name }}Server) *{{ $service.Name }}HTTPConverter {
func New{{ $service.Name }}HTTPConverter(srv {{ $service.Name }}HTTPService) *{{ $service.Name }}HTTPConverter {
return &{{ $service.Name }}HTTPConverter{
srv: srv,
}
}
{{ range $j, $method := $service.Methods }}
// {{ $method.Name }} returns {{ $service.Name }}Server interface's {{ $method.Name }} converted to http.HandlerFunc.
// {{ $method.Name }} returns {{ $service.Name }}HTTPService interface's {{ $method.Name }} converted to http.HandlerFunc.
{{ if ne $method.Comment "" -}}
//
// {{ $method.Comment }}
Expand Down Expand Up @@ -182,7 +192,7 @@ func (h *{{ $service.Name }}HTTPConverter) {{ $method.Name }}(cb func(ctx contex
})
}
// {{ $method.Name }}WithName returns Service name, Method name and {{ $service.Name }}Server interface's {{ $method.Name }} converted to http.HandlerFunc.
// {{ $method.Name }}WithName returns Service name, Method name and {{ $service.Name }}HTTPService interface's {{ $method.Name }} converted to http.HandlerFunc.
{{ if ne $method.Comment "" -}}
//
// {{ $method.Comment }}
Expand Down
15 changes: 10 additions & 5 deletions testdata/auth/auth.http.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 69e743c

Please sign in to comment.