serialization - Mikä on paras tapa käsitellä versiointia JSON-protokollan avulla?

Translate

Kirjoitan normaalisti kaikki koodin osat C # -merkiksi ja kirjoittaessani sarjaliikenneprotokollia käytän FastSerializeria, joka sarjoittaa / deserialisoi luokat nopeasti ja tehokkaasti. Se on myös erittäin helppokäyttöinen ja melko suoraviivainen tehdä "versioita", eli käsitellä sarjaversion eri versioita. Asia, jota normaalisti käytän, näyttää tältä:

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>();
}

ja

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);
}

Joten on helppo lisätä uusia asioita tai muuttaa sarjaliitäntää kokonaan, jos halutaan.

Haluan kuitenkin nyt käyttää JSONia syistä, jotka eivät ole merkityksellisiä juuri nyt =) Käytän tällä hetkelläDataContractJsonSerializerja etsin nyt tapaa saada sama joustavuus kuin yllä olevalla FastSerializerilla.

Joten kysymys on; mikä on paras tapa luoda JSON-protokolla / sarjallisuus ja pystyä kuvaamaan sarjallisuus kuten yllä, jotta en katkaise sarjoitusta vain siksi, että toinen kone ei ole vielä päivittänyt versionsa?

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

Kaikki vastaukset

Translate

Avain JSON-version versioon on aina lisätä uusia ominaisuuksia, älä koskaan poista tai nimeä uudelleen olemassa olevia ominaisuuksia. Tämä on samanlainen kuinkuinka protokollapuskurit käsittelevät versiointia.

Jos esimerkiksi aloitit seuraavalla JSON: lla:

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

Ja haluat nimetä "foo" -ominaisuuden uudeksi "bar", älä vain nimeä sitä uudelleen. Lisää sen sijaan uusi ominaisuus:

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

Koska et koskaan poista ominaisuuksia, vanhempiin versioihin perustuvat asiakkaat jatkavat toimintaansa. Tämän menetelmän haittapuoli on, että JSON voi paisua ajan myötä, ja sinun on jatkettava vanhojen ominaisuuksien ylläpitämistä.

On myös tärkeää määritellä selkeästi "reuna" tapauksesi asiakkaillesi. Oletetaan, että sinulla on taulukko-ominaisuus nimeltä "fooList". "FooList" -ominaisuus voi saada seuraavat mahdolliset arvot: ei ole olemassa / määrittelemätön (ominaisuutta ei ole fyysisesti JSON-objektissa tai se on olemassa ja se on asetettu "määrittelemättömäksi"), tyhjä, tyhjä luettelo tai luettelo, jossa on yksi tai useampi arvo. On tärkeää, että asiakkaat ymmärtävät miten käyttäytyä, erityisesti määrittelemättömissä / tyhjissä / tyhjissä tapauksissa.

Suosittelen myös lukemaan mitensemanttinen versiointitoimii. Jos otat semanttisen versiomallin käyttöön versionumeroissasi, taaksepäin yhteensopivia muutoksia voidaan tehdä pienemmille versioille, kun taas rikkovia muutoksia voidaan tehdä pääversioihin (sekä asiakkaiden että palvelinten on sovittava samasta pääversiosta) ). Vaikka tämä ei olekaan itse JSON: n ominaisuus, se on hyödyllinen kommunikoida tyypin muutoksista, joita asiakkaan tulisi odottaa version muuttuessa.

Lähde
Translate

Googlen Java-pohjainengson-kirjastoon erinomainen versiotuki jsonille. Se voi osoittautua erittäin käteväksi, jos ajattelet Java-tapaa.

On mukava ja helppo opetusohjelmatässä.

Lähde
Translate

Älä käytä DataContractJsonSerializeria, kuten nimessä sanotaan, tämän luokan kautta käsiteltävien objektien on:

a) Merkitään [DataContract] - ja [DataMember] -määritteillä.

b) Noudata ehdottomasti määriteltyä "sopimusta" eli ei vähempää eikä muuta kuin se on määritelty. Mahdollinen ylimääräinen tai puuttuva [DataMember] tekee deserialisoinnista poikkeuksen.

Jos haluat olla tarpeeksi joustava, käytä sitten JavaScriptSerializer-ohjelmaa, jos haluat valita halvan vaihtoehdon ... tai käytä tätä kirjastoa:

http://json.codeplex.com/

Tämä antaa sinulle riittävän hallinnan JSON-sarjoitukseen.

Kuvittele, että sinulla on esine sen alkuaikoina.

public class Customer
{ 
    public string Name;

    public string LastName;
}

Sarjallisuuden jälkeen se näyttää tältä:

{Nimi: "John", Sukunimi: "Doe"}

Jos muutat objektimäärittelyä lisäämään / poistamaan kenttiä. Deserialisaatio tapahtuu sujuvasti, jos käytät esimerkiksi JavaScriptSerializer-ohjelmaa.

public class Customer
{ 
    public string Name;

    public string LastName;

    public int Age;
}

Jos yrität poistaa viimeisen jsonin sarjallisuuden tästä uudesta luokasta, virhettä ei heitetä. Asia on, että uudet kentät asetetaan oletusarvoihinsa. Tässä esimerkissä: "Ikä" asetetaan nollaksi.

Voit sisällyttää omiin käytäntöihisi kaikissa kohteissasi olevan kentän, joka sisältää versionumeron. Tässä tapauksessa voit erottaa tyhjän kentän tai version epäjohdonmukaisuuden.

Joten sanotaan: Sinulla on luokkasi Asiakas v1 -sarja:

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

Haluat deserialisoida asiakkaan v2-ilmentymäksi, sinulla on:

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

Voit jotenkin havaita, mitkä objektisi kentät ovat jotenkin luotettavia ja mitkä eivät. Tässä tapauksessa tiedät, että v2-objektiesiintymäsi tulee v1-objektiinstanssista, joten kenttää Age ei pidä luottaa.

Muistan, että sinun tulee käyttää myös mukautettua määritettä, esim. "MinVersion", ja merkitä kukin kenttä tuetulla vähimmäisversiolla, jotta saat jotain tällaista:

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

    [MinVersion(1)]
    public string Name;

    [MinVersion(1)]
    public string LastName;

    [MinVersion(2)]
    public int Age;
}

Sitten voit myöhemmin käyttää tätä metadataa ja tehdä mitä tarvitset siinä.

Lähde
Translate

Sillä ei ole väliä mitä sarjaliitäntäkäytäntöä käytät, API-ohjelmointiversiot ovat yleensä samat.

Tarvitset yleensä:

  1. tapa, jolla kuluttaja voi kommunikoida tuottajalle hyväksymänsä API-version (vaikka tämä ei aina ole mahdollista)
  2. tuottajan tapa upottaa versiotiedot sarjoitettuihin tietoihin
  3. taaksepäin yhteensopiva strategia tuntemattomien kenttien käsittelemiseksi

Web-sovellusliittymässä yleensä kuluttajan hyväksymä sovellusliittymäversio on upotettu Hyväksy-otsikkoon (esimAccept: application/vnd.myapp-v1+json application/vnd.myapp-v2+jsontarkoittaa, että kuluttaja voi käsitellä joko sovellusliittymän versiota 1 ja 2) tai harvemmin URL-osoitteessa (esimhttps://api.twitter.com/1/statuses/user_timeline.json). Tätä käytetään yleensä pääversioissa (ts. Taaksepäin yhteensopimattomat muutokset). Jos palvelimella ja asiakkaalla ei ole yhteensopivaa Accept-otsikkoa, tiedonsiirto epäonnistuu (tai etenee parhaalla mahdollisella tavalla tai palaa oletusarvoiseen perustasoprotokollaan sovelluksen luonteesta riippuen).

Sitten tuottaja muodostaa sarjoitetut tiedot yhdessä pyydetyistä versioista ja upottaa sitten nämä versiotiedot sarjoitettuihin tietoihin (esim. Kenttään nimeltäversion). Kuluttajan tulisi käyttää tietojen upotettua versiotietoa määrittääkseen, miten sarjatuotteet jäsennetään. Datan versiotietojen tulisi myös sisältää pieniversio (ts. Taaksepäin yhteensopivien muutosten vuoksi), yleensä kuluttajien on voitava jättää huomiotta aliversiotiedot ja silti käsitellä tietoja oikein, vaikka aliversion ymmärtäminen voi antaa asiakkaalle mahdollisuuden tehdä lisäoletuksia miten tietoja tulisi käsitellä.

Yleinen strategia tuntemattomien kenttien käsittelemiseksi on esimerkiksi HTML: n ja CSS: n jäsentäminen. Kun kuluttaja näkee tuntemattomat kentät, hänen tulisi jättää se huomioimatta, ja kun tiedoista puuttuu kenttä, jonka asiakas odottaa, sen tulisi käyttää oletusarvoa; viestinnän luonteesta riippuen, voit myös haluta määrittää joitakin pakollisia kenttiä (ts. puuttuvia kenttiä pidetään kohtalokkaina virheinä). Pienissä versioissa lisättyjen kenttien tulee olla aina valinnaisia; aliversio voi lisätä valinnaisia kenttiä tai muuttaa semanttisia kenttiä, kunhan se on taaksepäin yhteensopiva, kun taas pääversio voi poistaa kenttiä tai lisätä pakollisia kenttiä tai muuttaa semanttisia taaksepäin yhteensopimattomalla tavalla.

Laajennettavissa sarjallisuusmuodoissa (kuten JSON tai XML) tietojen tulisi olla itse kuvaavia, toisin sanoen kenttien nimet tulisi aina tallentaa tietojen kanssa; sinun ei pitäisi luottaa siihen, että tietyt tiedot ovat saatavilla tietyistä paikoista.

Lähde
Leave a Reply
You must be logged in to post a answer.
Kirjailijasta
Ted