mirror of https://github.com/gin-gonic/gin.git
add jsonpb Render
This commit is contained in:
parent
3757142584
commit
ffcd9bf771
|
@ -23,6 +23,8 @@ import (
|
|||
"github.com/gin-contrib/sse"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/gin-gonic/gin/render"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Content-Type MIME of the most common data formats.
|
||||
|
@ -939,6 +941,12 @@ func (c *Context) JSON(code int, obj interface{}) {
|
|||
c.Render(code, render.JSON{Data: obj})
|
||||
}
|
||||
|
||||
// JSONPB serializes the given proto Message as JSON into the response body.
|
||||
// It also sets the Content-Type as "application/json".
|
||||
func (c *Context) JSONPB(code int, obj proto.Message) {
|
||||
c.Render(code, render.JSONPB{Data: obj, Option: protojson.MarshalOptions{EmitUnpopulated: true}})
|
||||
}
|
||||
|
||||
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
|
||||
// It also sets the Content-Type as "application/json".
|
||||
func (c *Context) AsciiJSON(code int, obj interface{}) {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package render
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// JSONPB contains the given proto.Message object.
|
||||
type JSONPB struct {
|
||||
Data proto.Message
|
||||
datapb json.RawMessage
|
||||
Option protojson.MarshalOptions
|
||||
}
|
||||
|
||||
// Render (JSONPB) writes data with custom ContentType.
|
||||
func (r JSONPB) Render(w http.ResponseWriter) (err error) {
|
||||
r.datapb, err = r.Option.Marshal(r.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writeContentType(w, jsonContentType)
|
||||
_, err = w.Write(r.datapb)
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteContentType (JSON) writes JSON ContentType.
|
||||
func (r JSONPB) WriteContentType(w http.ResponseWriter) {
|
||||
writeContentType(w, jsonContentType)
|
||||
}
|
|
@ -15,7 +15,9 @@ import (
|
|||
"testing"
|
||||
|
||||
testdata "github.com/gin-gonic/gin/testdata/protoexample"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
|
@ -510,3 +512,46 @@ func TestRenderReaderNoContentLength(t *testing.T) {
|
|||
assert.Equal(t, headers["Content-Disposition"], w.Header().Get("Content-Disposition"))
|
||||
assert.Equal(t, headers["x-request-id"], w.Header().Get("x-request-id"))
|
||||
}
|
||||
|
||||
func TestRenderJsonPb(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
reps := []int64{int64(1), int64(2)}
|
||||
typ := int32(11)
|
||||
label := "test"
|
||||
data := &testdata.Test{
|
||||
Label: &label,
|
||||
Type: &typ,
|
||||
Reps: reps,
|
||||
Optionalgroup: &testdata.Test_OptionalGroup{RequiredField: &label},
|
||||
}
|
||||
|
||||
r := (JSONPB{
|
||||
Data: data,
|
||||
datapb: []byte{},
|
||||
Option: protojson.MarshalOptions{
|
||||
EmitUnpopulated: true,
|
||||
},
|
||||
})
|
||||
r.WriteContentType(w)
|
||||
result, err := protojson.MarshalOptions{EmitUnpopulated: true}.Marshal(data)
|
||||
assert.NoError(t, err)
|
||||
err = r.Render(w)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, string(result), w.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
|
||||
|
||||
w1 := httptest.NewRecorder()
|
||||
r1 := (JSONPB{
|
||||
Data: nil,
|
||||
datapb: []byte{},
|
||||
Option: protojson.MarshalOptions{
|
||||
EmitUnpopulated: true,
|
||||
},
|
||||
})
|
||||
r1.WriteContentType(w)
|
||||
result2 := "{}"
|
||||
err1 := r1.Render(w1)
|
||||
assert.NoError(t, err1)
|
||||
assert.Equal(t, result2, w1.Body.String())
|
||||
assert.Equal(t, "application/json; charset=utf-8", w1.Header().Get("Content-Type"))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue