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
*/

 

'golang' 카테고리의 다른 글

golang init 함수 호출 시점  (0) 2024.07.05
golang 메모리 패딩 고려한 구조체 최적화  (0) 2024.07.05
golang Struct Embedding  (1) 2024.07.05
golang file scanner  (0) 2024.07.05
golang 정규식 문자열 치환  (0) 2024.07.05