/ / कस्टम JSON serialization और go-json में इंटरफेस के लिए deserialization, जाओ, serialization

गो-जेसन, जाओ, क्रमबद्धता में इंटरफेस के लिए कस्टम जेएसओएन क्रमबद्धता और deserialization

मैं वर्तमान में एक ब्लॉग के लिए एक JSON एपीआई विकसित कर रहा हूँगोलांग, और मैं ब्लॉग पोस्ट के क्रमबद्धता और deserialization को संभालने की कोशिश कर एक रोडब्लॉक में भाग गया है। मैं चाहता हूं कि मेरी पोस्ट में पोस्ट सेक्शन की एक सरणी हो जो कि कई चीजें हो सकती हैं (जैसे सामान्य अनुच्छेद, छवियां, उद्धरण इत्यादि। ।) मैं मोंगो का उपयोग भंडारण के लिए कर रहा हूं (अद्भुत के साथ एमजीओ पुस्तकालय) और मैं इस तरह की पोस्ट को सहेजना चाहता हूं:

{
"title": "Blog post",
"sections": [
{
"type": "text",
"content": { "en": "English content", "de": "Deutscher Inhalt" }
},
{
"type": "image",
"content": "https://dummyimage.com/100x100"
},
...more sections
],
...other fields
}

मैंने इसे लागू करने के लिए कई समाधानों की कोशिश की है और कोई भी वास्तव में ऐसा करने के लिए "सही तरीका" जैसा नहीं लग रहा है:

  1. सामग्री के बारे में परवाह नहीं है

यह एक साधारण संरचना का उपयोग कर, स्पष्ट समाधान की तरह लग रहा था:

type PostSection struct{
Type    string
Content interface{}
}

इस तरह, मैं जो भी फ्रंट पोस्ट पोस्ट करता हूं उसे सहेज सकता हूं और इसे सहेज सकता हूं। हालांकि, डेटा में हेरफेर करना या इसे मान्य करना असंभव हो जाता है, इसलिए यह एक अच्छा समाधान नहीं है।

  1. कस्टम इंटरफेस serialization का उपयोग करना

मुझे मिला यह लेख गोलांग में इंटरफेस को क्रमबद्ध करने के बारे में। यह पहली बार बहुत अच्छा लग रहा था, क्योंकि मेरे पास इस तरह का इंटरफेस हो सकता था:

type PostSection interface{
Type()    string
Content() interface{}
}

और फिर इस तरह के हर प्रकार को लागू करें:

type PostImage string

func (p *PostImage) Type() string {
return "image"
}

func (p *PostImage) Content() interface{} {
return p
}

सबसे अच्छा, यह "यह किया गया था, और लागू करने के बाद MarshalJSON तथा UnmarshalJSON मेरे सभी प्रकार के लिए, यह जेसन का उपयोग करते समय ठीक काम कर रहा था। सीधे एक पोस्टसेक्शन ऑब्जेक्ट पर मार्शल।

हालांकि, जब एक संपूर्ण पोस्ट ऑब्जेक्ट को क्रमबद्ध या deserializing जब एक सरणी है PostSectionएस, मेरे कस्टम कोड को अभी अनदेखा किया जा रहा था और पोस्टसेक्शन को अंतर्निहित वस्तुओं के रूप में माना जाएगा (string या map[string]string उदाहरणों में) जब serializing, या deserializing जब खाली वस्तुओं में परिणाम।

  1. संपूर्ण पोस्ट स्ट्रक्चर के लिए कस्टम सीरियलाइजेशन लिखना

तो, समाधान मैं वर्तमान में उपयोग कर रहा हूँ लेकिन होगाबदलने के लिए पूरे पोस्ट ऑब्जेक्ट के लिए कस्टम serialization है। यह सुपर बदसूरत कोड की ओर जाता है, क्योंकि मुझे केवल एक ही क्षेत्र के लिए वास्तव में कस्टम कोड की आवश्यकता होती है और इसलिए मैं बाकी के माध्यम से गुजर रहा हूं, जिससे deserialization इस तरह दिखता है:

p.ID = decoded.ID
p.Author = decoded.Author
p.Title = decoded.Title
p.Intro = decoded.Intro
p.Slug = decoded.Slug
p.TitleImage = decoded.TitleImage
p.Images = decoded.Images
...more fields...

और फिर, इस तरह के खंडों को डीकोड करना:

sections := make([]PostSection, len(decoded.Sections))
for i, s := range decoded.Sections {
if s["type"] == "text" {
content := s["content"].(map[string]interface{})
langs := make(PostText, len(content))
for lang, langContent := range content {
langString := langContent.(string)
langs[lang] = langString
}
sections[i] = &langs
} else if s["type"] == "image" {
content := s["content"].(string)
contentString := PostImage(content)
sections[i] = &contentString
}
}

p.Sections = sections

यह एक बहुत सारे कोड है जिसे मुझे उपयोग करना होगाहर बार जब मैं किसी अन्य रूप में पोस्टसेक्शन को किसी अन्य रूप में शामिल करना चाहता हूं (उदाहरण के लिए न्यूजलेटर में) और यह लंबे शॉट से बेवकूफ कोड को महसूस नहीं करता है। इसके अलावा, विकृत वर्गों के लिए कोई त्रुटि नहीं है - वे सिर्फ एक दहशत जैसे इस।

क्या इस समस्या का कोई साफ समाधान है?

उत्तर:

जवाब के लिए 2 № 1

लेखन से बचने के लिए UnmarshalJSON सभी के लिए Post आप अपना लपेट सकते हैं PostSection एक ठोस प्रकार में और इसे Unmarshaler इंटरफ़ेस को कार्यान्वित किया है।

type Post struct {
ID         int
Author     string
Title      string
Intro      string
Slug       string
TitleImage string
Images     []string

Sections []*PostSection
}

type SectionContent interface {
Type()    string
Content() interface{}
}

type PostSection struct {
Content SectionContent
}

func (s *PostSection) UnmarshalJSON(data []byte) error {
// ...
return nil
}