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" 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" httpclient "github.com/Unity-Technologies/truss/cmd/_integration-tests/transport/transportpermutations-service/svc/client/http"
"github.com/golang/protobuf/jsonpb"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -643,7 +644,21 @@ func testHTTP(
t.Fatal(errors.Wrap(err, "cannot make http request")) 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 { if err != nil {
t.Fatal(errors.Wrapf(err, "json error, got response: %q", string(respBytes))) t.Fatal(errors.Wrapf(err, "json error, got response: %q", string(respBytes)))
} }

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

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

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

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