Use jsonpb to (un)marshall messages to/from JSON

The stdlib encoding/json package isn't able to (un)marshal some advanced protobuf features such as `oneof` fields, so jsonpb should be used instead
This commit is contained in:
Paul Nicholls 2017-08-09 13:57:11 +12:00 коммит произвёл Tye McQueen
Родитель 5028228e97
Коммит a2130ecb9d
4 изменённых файлов: 32 добавлений и 7 удалений

Просмотреть файл

@ -17,6 +17,7 @@ import (
pb "github.com/Unity-Technologies/truss/cmd/_integration-tests/transport/proto"
httpclient "github.com/Unity-Technologies/truss/cmd/_integration-tests/transport/transportpermutations-service/svc/client/http"
"github.com/golang/protobuf/jsonpb"
"github.com/pkg/errors"
)
@ -643,7 +644,21 @@ func testHTTP(
t.Fatal(errors.Wrap(err, "cannot make http request"))
}
err = json.Unmarshal(respBytes, &resp)
switch v := resp.(type) {
case *pb.GetWithQueryResponse:
err = jsonpb.UnmarshalString(string(respBytes), v)
case *pb.GetWithRepeatedQueryResponse:
err = jsonpb.UnmarshalString(string(respBytes), v)
case *pb.GetWithEnumQueryResponse:
err = jsonpb.UnmarshalString(string(respBytes), v)
case *pb.PostWithNestedMessageBodyResponse:
err = jsonpb.UnmarshalString(string(respBytes), v)
case *pb.MetaResponse:
err = jsonpb.UnmarshalString(string(respBytes), v)
default:
t.Fatalf("Unknown response type: %T", v)
}
if err != nil {
t.Fatal(errors.Wrapf(err, "json error, got response: %q", string(respBytes)))
}

Просмотреть файл

@ -92,6 +92,10 @@ import (
"strings"
"context"
{{ if len .HTTPHelper.Methods -}}
"github.com/golang/protobuf/jsonpb"
{{- end }}
"github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
"github.com/pkg/errors"
@ -227,7 +231,7 @@ func contextValuesToHttpHeaders(keys []string) httptransport.RequestFunc {
}
var resp pb.{{GoName $method.ResponseType}}
if err = json.Unmarshal(buf, &resp); err != nil {
if err = jsonpb.UnmarshalString(string(buf), &resp); err != nil {
return nil, errorDecoder(buf)
}

Просмотреть файл

@ -14,7 +14,7 @@ var ServerDecodeTemplate = `
return nil, errors.Wrapf(err, "cannot read body of http request")
}
if len(buf) > 0 {
if err = json.Unmarshal(buf, &req); err != nil {
if err = jsonpb.UnmarshalString(string(buf), &req); err != nil {
const size = 8196
if len(buf) > size {
buf = buf[:size]
@ -67,6 +67,9 @@ import (
"strings"
"io"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
"context"
"github.com/gorilla/mux"
@ -173,9 +176,12 @@ func (h httpError) Headers() http.Header {
// EncodeHTTPGenericResponse is a transport/http.EncodeResponseFunc that encodes
// the response as JSON to the response writer. Primarily useful in a server.
func EncodeHTTPGenericResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
return encoder.Encode(response)
marshaller := jsonpb.Marshaler{
EnumsAsInts: true,
EmitDefaults: true,
}
return marshaller.Marshal(w, response.(proto.Message))
}
// Helper functions

Просмотреть файл

@ -163,7 +163,7 @@ func DecodeHTTPSumZeroRequest(_ context.Context, r *http.Request) (interface{},
return nil, errors.Wrapf(err, "cannot read body of http request")
}
if len(buf) > 0 {
if err = json.Unmarshal(buf, &req); err != nil {
if err = jsonpb.UnmarshalString(string(buf), &req); err != nil {
const size = 8196
if len(buf) > size {
buf = buf[:size]