serialization - JSON प्रोटोकॉल का उपयोग करके संस्करण को संभालने का सबसे अच्छा तरीका क्या है?

Translate

मैं आम तौर पर C # में कोड के सभी हिस्सों को लिख रहा हूं और जब प्रोटोकॉल लिखा जाता है तो मैं FastSerializer का उपयोग करता हूं जो कि वर्गों को तेजी से और कुशल ढंग से क्रमांकित / deserializes। यह भी उपयोग करने के लिए बहुत आसान है, और "वर्जनिंग" करने के लिए काफी सीधा-सीधा है, अर्थात क्रमांकन के विभिन्न संस्करणों को संभालने के लिए। आमतौर पर मैं जिस चीज का उपयोग करता हूं, वह इस तरह दिखती है:

public override void DeserializeOwnedData(SerializationReader reader, object context)
{
    base.DeserializeOwnedData(reader, context);
    byte serializeVersion = reader.ReadByte(); // used to keep what version we are using

    this.CustomerNumber = reader.ReadString();
    this.HomeAddress = reader.ReadString();
    this.ZipCode = reader.ReadString();
    this.HomeCity = reader.ReadString();
    if (serializeVersion > 0)
        this.HomeAddressObj = reader.ReadUInt32();
    if (serializeVersion > 1)
        this.County = reader.ReadString();
    if (serializeVersion > 2)
        this.Muni = reader.ReadString();
    if (serializeVersion > 3)
        this._AvailableCustomers = reader.ReadList<uint>();
}

तथा

public override void SerializeOwnedData(SerializationWriter writer, object context)
{            
    base.SerializeOwnedData(writer, context);
    byte serializeVersion = 4; 
    writer.Write(serializeVersion);


    writer.Write(CustomerNumber);
    writer.Write(PopulationRegistryNumber);            
    writer.Write(HomeAddress);
    writer.Write(ZipCode);
    writer.Write(HomeCity);
    if (CustomerCards == null)
        CustomerCards = new List<uint>();            
    writer.Write(CustomerCards);
    writer.Write(HomeAddressObj);

    writer.Write(County);

    // v 2
    writer.Write(Muni);

    // v 4
    if (_AvailableCustomers == null)
        _AvailableCustomers = new List<uint>();
    writer.Write(_AvailableCustomers);
}

इसलिए नई चीजों को जोड़ना आसान है, या यदि कोई चुनता है तो पूरी तरह से क्रमांकन को बदल दें।

हालाँकि, मैं अब JSON का उपयोग उन कारणों के लिए नहीं करना चाहता जो अभी प्रासंगिक नहीं हैं =) मैं वर्तमान में उपयोग कर रहा हूंDataContractJsonSerializerऔर मैं अब उसी लचीलेपन के लिए रास्ता ढूंढ रहा हूं जिसका मैंने ऊपर FastSerializer का उपयोग किया है।

तो सवाल है; JSON प्रोटोकॉल / क्रमांकन बनाने के लिए और ऊपर के रूप में क्रमांकन का विस्तार करने में सक्षम होने के लिए सबसे अच्छा तरीका क्या है, ताकि मैं क्रमांकन को केवल इसलिए नहीं तोड़ूं क्योंकि एक अन्य मशीन ने अभी तक अपने संस्करण को अपडेट नहीं किया है?

This question and all comments follow the "Attribution Required."

सभी उत्तर

Translate

JSON को संस्करणित करने की कुंजी हमेशा नई संपत्तियों को जोड़ना है, और मौजूदा गुणों को कभी भी हटा या नाम बदलना नहीं है। इस के समान हैकैसे प्रोटोकॉल बफ़र्स संस्करण को संभालते हैं.

उदाहरण के लिए, यदि आपने निम्नलिखित JSON से शुरुआत की है:

{
  "version": "1.0",
  "foo": true
}

और आप "फू" संपत्ति का नाम "बार" में बदलना चाहते हैं, बस नाम बदलें नहीं। इसके बजाय, एक नई संपत्ति जोड़ें:

{
  "version": "1.1",
  "foo": true,
  "bar": true
}

चूंकि आप कभी भी गुण नहीं निकाल रहे हैं, पुराने संस्करणों पर आधारित क्लाइंट काम करना जारी रखेंगे। इस पद्धति का नकारात्मक पक्ष यह है कि JSON समय के साथ फूला हुआ हो सकता है, और आपको पुरानी संपत्तियों को बनाए रखना होगा।

अपने ग्राहकों को अपने "किनारे" के मामलों को स्पष्ट रूप से परिभाषित करना भी महत्वपूर्ण है। मान लीजिए कि आपके पास "fooList" नामक एक सरणी संपत्ति है। "FooList" संपत्ति निम्नलिखित संभावित मूल्यों पर ले सकती है: मौजूद नहीं है / अपरिभाषित नहीं है (संपत्ति JSON ऑब्जेक्ट में भौतिक रूप से मौजूद नहीं है, या यह मौजूद है और "अपरिभाषित" पर सेट है), रिक्त, रिक्त सूची या के साथ एक सूची एक या अधिक मूल्य। यह महत्वपूर्ण है कि ग्राहक समझें कि कैसे व्यवहार करना है, खासकर अपरिभाषित / अशक्त / खाली मामलों में।

मैं यह भी पढ़ने की सलाह दूंगा कि कैसेशब्दार्थ संस्करणकाम करता है। यदि आप अपने वर्जन नंबरों के लिए सिमेंटिक वर्जनिंग स्कीम शुरू करते हैं, तो बैकवर्ड संगत बदलाव मामूली संस्करण सीमा पर किए जा सकते हैं, जबकि ब्रेकिंग परिवर्तन एक प्रमुख संस्करण सीमा पर किए जा सकते हैं (क्लाइंट और सर्वर दोनों को एक ही प्रमुख संस्करण पर सहमत होना होगा। ) है। हालांकि यह JSON की संपत्ति नहीं है, लेकिन यह उस प्रकार के परिवर्तनों के संचार के लिए उपयोगी है, जब क्लाइंट को संस्करण में बदलाव की उम्मीद करनी चाहिए।

स्रोत
Translate

गूगल का जावा आधारितgson पुस्तकालयjson के लिए एक उत्कृष्ट संस्करण समर्थन है। यह एक बहुत ही उपयोगी साबित हो सकता है अगर आप सोच रहे हैं जावा रास्ता।

अच्छा और आसान ट्यूटोरियल हैयहाँ.

स्रोत
Translate

DataContractJsonSerializer का उपयोग न करें, जैसा कि नाम में कहा गया है, इस वर्ग के माध्यम से संसाधित होने वाली वस्तुओं को निम्न करना होगा:

a) [DataContract] और [DataMember] विशेषताओं के साथ चिह्नित किया जाए।

बी) परिभाषित "अनुबंध" के साथ कड़ाई से अनुपालन करें, जो कि कुछ भी कम नहीं है और कुछ भी नहीं है जो इसे परिभाषित किया गया है। कोई भी अतिरिक्त या अनुपलब्ध [DataMember] अपवाद को फेंकने के लिए deserialization करेगा।

यदि आप पर्याप्त लचीला होना चाहते हैं, तो यदि आप सस्ते विकल्प के लिए जाना चाहते हैं, तो JavaScriptSerializer का उपयोग करें ... या इस लाइब्रेरी का उपयोग करें:

http://json.codeplex.com/

यह आपको आपके JSON क्रमांकन पर पर्याप्त नियंत्रण देगा।

कल्पना कीजिए कि आप अपने शुरुआती दिनों में एक वस्तु है।

public class Customer
{ 
    public string Name;

    public string LastName;
}

एक बार धारावाहिक के बाद यह इस तरह दिखाई देगा:

{नाम: "जॉन", लास्टनेम: "डो"}

यदि आप फ़ील्ड जोड़ने / हटाने के लिए अपनी ऑब्जेक्ट परिभाषा बदलते हैं। यदि आप उपयोग करते हैं, तो उदाहरण के लिए, जावास्क्रिप्ट का उपयोग सुचारू रूप से किया जाएगा।

public class Customer
{ 
    public string Name;

    public string LastName;

    public int Age;
}

यदि यो इस नए वर्ग के लिए अंतिम जसन को डी-सीरियल करने की कोशिश करते हैं, तो कोई त्रुटि नहीं होगी। बात यह है कि आपके नए क्षेत्र उनके डिफ़ॉल्ट पर सेट हो जाएंगे। इस उदाहरण में: "आयु" को शून्य पर सेट किया जाएगा।

आप अपने स्वयं के सम्मेलनों में, अपनी सभी वस्तुओं में मौजूद एक फ़ील्ड शामिल कर सकते हैं, जिसमें संस्करण संख्या शामिल है। इस मामले में आप एक खाली क्षेत्र या एक संस्करण असंगतता के बीच अंतर बता सकते हैं।

तो हम कहते हैं: आप अपने वर्ग ग्राहक v1 serialized है:

{ Version: 1, LastName: "Doe", Name: "John" }

आप एक ग्राहक v2 उदाहरण में डिसेरिएलाइज़ करना चाहते हैं, आपके पास होगा:

{ Version: 1, LastName: "Doe", Name: "John", Age: 0}

आप किसी भी तरह से पता लगा सकते हैं कि आपकी वस्तु में कौन से क्षेत्र हैं जो किसी भी तरह विश्वसनीय हैं और क्या नहीं। इस स्थिति में आप जानते हैं कि आपका v2 ऑब्जेक्ट इंस्टेंस एक v1 ऑब्जेक्ट इंस्टेंस से आ रहा है, इसलिए फील्ड एज पर भरोसा नहीं किया जाना चाहिए।

मुझे ध्यान में रखना चाहिए कि आपको एक कस्टम विशेषता का भी उपयोग करना चाहिए, जैसे "MinVersion", और प्रत्येक फ़ील्ड को न्यूनतम समर्थित संस्करण संख्या के साथ चिह्नित करें, ताकि आपको कुछ ऐसा मिल जाए:

public class Customer
{ 
    [MinVersion(1)]
    public int Version;

    [MinVersion(1)]
    public string Name;

    [MinVersion(1)]
    public string LastName;

    [MinVersion(2)]
    public int Age;
}

फिर बाद में आप इस मेटा-डेटा को एक्सेस कर सकते हैं और इसके लिए आपको जो भी आवश्यक हो वह कर सकते हैं।

स्रोत
Translate

इससे कोई फर्क नहीं पड़ता कि आप किस धारावाहिक प्रोटोकॉल का उपयोग करते हैं, एपीआई की तकनीकें आमतौर पर समान होती हैं।

आम तौर पर आप की जरूरत है:

  1. उपभोक्ता के लिए एक तरीका है कि वह जिस एपीआई संस्करण को स्वीकार करे, निर्माता से संवाद करे (हालांकि यह हमेशा संभव नहीं होता है)
  2. निर्माता के लिए एक तरह से क्रमबद्ध डेटा के लिए संस्करण जानकारी एम्बेड करने के लिए
  3. अज्ञात क्षेत्रों को संभालने के लिए एक पिछड़ी संगत रणनीति

एक वेब एपीआई में, आम तौर पर एपीआई संस्करण जिसे उपभोक्ता स्वीकार करता है स्वीकार किए जाते हैं हेडर (जैसेAccept: application/vnd.myapp-v1+json application/vnd.myapp-v2+jsonइसका मतलब है कि उपभोक्ता आपके एपीआई के संस्करण 1 और संस्करण 2 को संभाल सकता है) या आमतौर पर यूआरएल में (जैसे)https://api.twitter.com/1/statuses/user_timeline.json) है। यह आम तौर पर प्रमुख संस्करणों (यानी पिछड़े असंगत परिवर्तन) के लिए उपयोग किया जाता है। यदि सर्वर और क्लाइंट में एक मेल खाता हैडर नहीं है, तो संचार विफल हो जाता है (या आवेदन के स्वरूप के आधार पर सर्वोत्तम आधार के आधार पर या डिफ़ॉल्ट बेसलाइन प्रोटोकॉल में गिरावट)।

निर्माता तब अनुरोधित संस्करण में से एक में क्रमबद्ध डेटा उत्पन्न करता है, फिर इस संस्करण की जानकारी को क्रमबद्ध डेटा (जैसे नाम वाले क्षेत्र) में एम्बेड करता हैversion) है। उपभोक्ता को क्रमबद्ध डेटा को पार्स करने के तरीके को निर्धारित करने के लिए डेटा में एम्बेडेड संस्करण जानकारी का उपयोग करना चाहिए। डेटा में संस्करण की जानकारी में मामूली संस्करण भी होना चाहिए (यानी पिछड़े संगत परिवर्तनों के लिए), आमतौर पर उपभोक्ताओं को मामूली संस्करण की जानकारी को अनदेखा करने में सक्षम होना चाहिए और फिर भी डेटा को सही ढंग से संसाधित करना चाहिए, हालांकि मामूली संस्करण को समझने से ग्राहक को इसके बारे में अतिरिक्त धारणा बनाने की अनुमति मिल सकती है। डेटा को कैसे संसाधित किया जाना चाहिए।

अज्ञात फ़ील्ड्स को हैंडल करने की एक सामान्य रणनीति यह है कि HTML और CSS को कैसे पार्स किया जाता है। जब उपभोक्ता एक अज्ञात फ़ील्ड देखता है, तो उन्हें इसे अनदेखा करना चाहिए, और जब डेटा एक फ़ील्ड को याद कर रहा है जो ग्राहक अपेक्षा कर रहा है, तो उसे डिफ़ॉल्ट मान का उपयोग करना चाहिए; संचार की प्रकृति के आधार पर, आप कुछ फ़ील्ड्स को भी निर्दिष्ट करना चाह सकते हैं जो अनिवार्य हैं (अर्थात लापता फ़ील्ड को घातक त्रुटि माना जाता है)। मामूली संस्करणों के भीतर जोड़े गए फ़ील्ड हमेशा वैकल्पिक फ़ील्ड होने चाहिए; मामूली संस्करण वैकल्पिक फ़ील्ड जोड़ सकते हैं या जब तक यह पिछड़ा संगत है, तब तक शब्दार्थ को बदल सकते हैं, जबकि प्रमुख संस्करण फ़ील्ड को हटा सकते हैं या अनिवार्य फ़ील्ड जोड़ सकते हैं या किसी पिछड़े असंगत तरीके से फ़ील्ड बदल सकते हैं।

एक एक्स्टेंसिबल क्रमांकन प्रारूप (जैसे JSON या XML) में, डेटा को स्व-वर्णनात्मक होना चाहिए, दूसरे शब्दों में, फ़ील्ड नामों को हमेशा डेटा के साथ संग्रहीत किया जाना चाहिए; आपको विशिष्ट पदों पर उपलब्ध विशिष्ट डेटा पर निर्भर नहीं होना चाहिए।

स्रोत
Leave a Reply
You must be logged in to post a answer.
लेखक के बारे में
Ted