golang
golang json gojay 라이브러리
kimbs0301
2024. 7. 5. 17:26
서버와 클라이언트 간 연동 시 구조체를 json으로 변환해서 할 경우 gojay 라이브러리의 Marshal 함수를 사용하면
json 생성을 golang에서 제공하는 라이브러리보다 좋은 성능을 낼 수 있다.
gojay를 사용할 경우 구조체 별로 MarshalJSONObject 함수 정의가 필요하다.
// Package main
package main // import "example.com/gojay/main"
import (
"bytes"
"encoding/json"
"fmt"
"testing"
"github.com/francoispqt/gojay"
)
func Test1(t *testing.T) {
a := Address{Text: "a", Post: 1, Enabled: true}
c := &Car{Name: "a", Size: 1}
p1 := Phone{Name: "a", Number: 1}
p2 := Phone{Name: "2", Number: 1}
var p PhoneSlice
p = append(p, p1, p2)
fm1 := FamilyMember{Name: "a", Age: 1, Phone: p}
fm2 := FamilyMember{Name: "a", Age: 1, Address: Address{Text: "b", Post: 21, Enabled: true}}
var fm FamilyMemberSlice
fm = append(fm, fm1, fm2)
v1 := Person{
Name: "a",
Age: 1,
BirthTime: 1,
FriendName: []string{"a", "b"},
FriendAge: []int{1, 2},
Descr: "123",
Address: a,
Car: c,
FamilyMember: fm,
Enabled: true,
}
b, err := gojay.MarshalJSONObject(&v1)
if err != nil {
fmt.Printf("%s\n", err.Error())
}
JsonPrettyDebugByBytes(b)
v2 := Person{}
err = gojay.UnmarshalJSONObject(b, &v2)
if err != nil {
fmt.Printf("%s\n", err.Error())
}
bs, _ := json.Marshal(v2)
fmt.Printf("json.Marshal %s\n", string(bs))
}
func JsonPrettyDebugByBytes(src []byte) {
var buf bytes.Buffer
json.Indent(&buf, src, "", " ")
fmt.Printf("%s\n", string(buf.Bytes()))
}
type Person struct {
Name string
Age int
BirthTime int64
FriendName []string
FriendAge []int
Descr interface{}
Address Address
Car *Car
FamilyMember FamilyMemberSlice
Enabled bool
}
type Address struct {
Text string
Post int
Enabled bool
}
type Car struct {
Name string
Size int
}
type FamilyMember struct {
Name string
Age int
Phone PhoneSlice
Address Address
}
type FamilyMemberSlice []FamilyMember
type Phone struct {
Name string
Number int
}
type PhoneSlice []Phone
/**
MarshalJSON ---
*/
func (p *Person) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("Name", p.Name)
enc.IntKey("Age", p.Age)
enc.Int64Key("BirthTime", p.BirthTime)
if len(p.FriendName) > 0 {
enc.SliceStringKey("FriendName", p.FriendName)
}
if len(p.FriendAge) > 0 {
enc.SliceIntKey("FriendAge", p.FriendAge)
}
enc.StringKey("Descr", p.Descr.(string))
if p.Address.Text != "" {
enc.ObjectKey("Address", &p.Address)
}
enc.ObjectKey("Car", p.Car)
if len(p.FamilyMember) > 0 {
enc.ArrayKey("FamilyMember", p.FamilyMember)
}
enc.BoolKey("Enabled", p.Enabled)
}
func (p *Person) IsNil() bool {
return p == nil
}
func (a *Address) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("Text", a.Text)
enc.IntKey("Post", a.Post)
enc.BoolKey("Enabled", a.Enabled)
}
func (a *Address) IsNil() bool {
return a == nil
}
func (c *Car) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("Name", c.Name)
enc.IntKey("Size", c.Size)
}
func (c *Car) IsNil() bool {
return c == nil
}
func (f *FamilyMember) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("Name", f.Name)
enc.IntKey("Age", f.Age)
if len(f.Phone) > 0 {
enc.ArrayKey("Phone", f.Phone)
}
if f.Address.Text != "" {
enc.ObjectKey("Address", &f.Address)
}
}
func (f *FamilyMember) IsNil() bool {
return f == nil
}
func (p *Phone) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("Name", p.Name)
enc.IntKey("Number", p.Number)
}
func (p *Phone) IsNil() bool {
return p == nil
}
func (f FamilyMemberSlice) MarshalJSONArray(enc *gojay.Encoder) {
for _, v := range f {
enc.Object(&v)
}
}
func (f FamilyMemberSlice) IsNil() bool {
return len(f) == 0
}
func (p PhoneSlice) MarshalJSONArray(enc *gojay.Encoder) {
for _, v := range p {
enc.Object(&v)
}
}
func (p PhoneSlice) IsNil() bool {
return len(p) == 0
}
/**
--- MarshalJSON
*/