1. 程式人生 > >golang下如何仿django實現serializer,十分適用!

golang下如何仿django實現serializer,十分適用!

如何實現serializer用golang

對返回的model進行 django裡的 toRepresentation()操作(update,pop,picked)
目前只針對json編碼方式,其他方式待跟進
serializer實現如下:

package serializer

import (
	"encoding/json"
	"github.com/fwhezfwhez/errorx"
)

// A block type aims to mapper the origin struct to a map[string]interface{}
// For Instance:
//   struct{
// Name string // Age int // }{ // Name: "fwhezfwhez", // Age: 9, // } // The Block of the struct would be a map[string]interface{} {"name":"ft","age":9} // type Block map[string]interface{} func (b *Block) Update(key string, value interface{})*Block{ (*b)[key] = value return b } func (b *Block) Pop(key string
)*Block{ delete(*b, key) return b } type SerializerI interface{ Serialize(dest interface{},f func(b Block)(func(b Block)Block,[]string))([]byte,error) } // a json serializer realization type JsonSerializer struct{ } func (s JsonSerializer) Serialize(dest interface{},f func(b Block)(func(b Block)
Block,[]string))([]byte,error){ //1. transfer the struct to a map var m = make(Block,0) buf, er :=json.Marshal(dest) if er!=nil { return nil, errorx.New(er) } er = json.Unmarshal(buf,&m) if er!=nil { return nil, errorx.New(er) } //2. handle picked fields into the map blockHandler,picked :=f(m) //2.1 get filtered fields , get all fields if picked is nil or len=0 var filtPicked Block if picked ==nil || len(picked) ==0{ filtPicked = m }else{ filtPicked = make(Block,0) for _,v :=range picked{ vm,ok := m[v] if !ok { continue } filtPicked[v] = vm } } //2.2 change fields with the updated and popped staff buf, er = json.Marshal(blockHandler(filtPicked)) if er != nil { return nil, errorx.Wrap(er) } return buf, nil }

如何使用

go get github.com/fwhezfwhez/go-serializer

package main

import (
	"encoding/json"
	"fmt"
	"github.com/fwhezfwhez/go-serializer"
	"time"
)

type User struct {
	serializer.SerializerI
	Name      string    `json:"name"`
	Age       int       `json:"age"`
	Salary    float64   `json:"salary"`
	CreatedAt time.Time `json:"created_at"`
}

func (u User) ToRepresentation(f func(serializer.Block) (func(b serializer.Block) serializer.Block, []string)) ([]byte, error) {
	return u.Serialize(u, f)
}

func main() {
	u := User{
		SerializerI: serializer.JsonSerializer{},
		Name:      "ft2",
		Age:       9,
		Salary:    1000,
		CreatedAt: time.Now(),
	}

	buf, er := u.ToRepresentation(func(m serializer.Block) (func(b serializer.Block) serializer.Block, []string) {
		// abandon the 'Salary' field,use 'pick:= []string(nil)' to stand for all picked
		pick := []string{"age", "created", "name"}
		handler := func(b serializer.Block) serializer.Block {
			// update
			b.Update("question", "why?")
			b.Update("location", "china")
			// pop
			b.Pop("location")
			// rewrite
			b.Update("created_at", u.CreatedAt.Format("2006-01-02 15:04:05"))
			return b
		}
		return handler, pick
	})
	if er != nil {
		fmt.Println(er.Error())
		return
	}
	// the result of buf is a json []byte
	fmt.Println(string(buf))
	// if you want a further operator to the json map,get it by:
	var m map[string]interface{}
	json.Unmarshal(buf, &m)
	fmt.Println(m)
}

result:

{"age":9,"created_at":"2018-10-15 09:55:24","name":"ft2","question":"why?"}
map[age:9 created_at:2018-10-15 09:55:24 name:ft2 question:why?]