2016-06-01 8 views
2

私は、さまざまなソースからJSONオブジェクトを収集し、それらを単一のJSONオブジェクトに集約するGoサービスを作成しています。GoでのJSONオブジェクトの集約

子オブジェクトをアンマーシャリングして再マーシャリングしたり、手動でJSON文字列を作成したりせずに、子オブジェクトを集約する方法があるかどうかは疑問でした。

私はこのような既に整列化部分を含むstructを使用して考えた:

type Event struct { 
    Place  string `json:"place"` 
    Attendees string `json:"attendees"` 
} 

どこPlaceAttendeesはJSONが自分自身を文字列です。私は何とかそれらを "すでに整列化されている"とマークしたいので、エスケープされたJSON文字列として終わらず代わりにそのまま使用されます。

これを達成する方法はありますか?

答えて

3

はい、Marshalerインターフェイスを実装するカスタムタイプを使用できます。

https://play.golang.org/p/YB_eKlfOND

package main 

import (
    "fmt" 
    "encoding/json" 
) 

type Event struct { 
    Place  RawString `json:"place"` 
    Attendees RawString `json:"attendees,omitempty"` 
} 

type RawString string 

func (s RawString) MarshalJSON() ([]byte, error) { 
    return []byte(s), nil 
} 

func main() { 
    event := Event{ 
     Place: RawString(`{"name":"Paris"}`), 
     Attendees: RawString(`[{"name":"John"}, {"name":"Juli"}]`), 
    } 
    s, err := json.Marshal(event) 
    fmt.Println(fmt.Sprintf("event: %v; err: %v", string(s), err)) 
} 
+0

でしたしかし、それはbase64にエンコードします。実例がありますか?私はどこで間違っていたのかを確認することができて嬉しいです。 –

4

あなたはjson.RawMessage

RawMessageは生のエンコードされたJSONオブジェクトで使用することができます。これは、マーシャラーとアンマーシャラーを実装しており、JSONのデコードを遅らせたり、JSONエンコーディングを事前に計算したりするために使用できます。

また、json.RawMessage[]byteへのエイリアスですので、あなたはそれまでの値このようすることができます

v := json.RawMessage(`{"foo":"bar"}`) 

例:@KarrotKake、RawMessageは、私が試した最初のもの

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Event struct { 
    Place  json.RawMessage `json:"place"` 
    Attendees json.RawMessage `json:"attendees"` 
} 

func main() { 
    e := Event{ 
     Place: json.RawMessage(`{"address":"somewhere"}`), 
     Attendees: json.RawMessage(`{"key":"value"}`), 
    } 
    c, err := json.Marshal(&e) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(string(c)) 
    // {"place":{"address":"somewhere"},"attendees":{"key":"value"}} 
} 
+0

RawMessageを使用しようとしましたが、文字列をbase64にエンコードします。あなたは実例を提供できますか?ちょうど私が試したものだったように、好奇心が強い。 –

+0

私は 'RawMessage'を実際に' string 'ではなく[[] byte'であり、base64でもエンコードされた内容として試しました。この問題を回避する方法がある場合は... – Jukurrpa

+0

@ Jukurrpaでは、カスタムクラスを 'type RawBytes [] byte'型として継承できます。 'RawMessage'についても気にしています。 –