programing

JSON 프로토콜을 사용하여 버전 관리를 처리하는 가장 좋은 방법은 무엇입니까?

closeapi 2023. 2. 25. 21:00
반응형

JSON 프로토콜을 사용하여 버전 관리를 처리하는 가장 좋은 방법은 무엇입니까?

나는 보통 C#에 코드의 모든 부분을 쓰고 있으며, 직렬화된 프로토콜을 쓸 때는 클래스를 빠르고 효율적으로 직렬화/비직렬화하는 FastSerializer를 사용한다.또, 「버전 관리」(즉, 다른 버전의 시리얼라이제이션의 처리)는, 매우 간단하게 실시할 수 있습니다.제가 평소에 사용하는 것은 다음과 같습니다.

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 프로토콜/시리얼라이제이션(serialization)을 만들고 위와 같이 시리얼라이제이션(serialization)을 상세하게 할 수 있는 가장 좋은 방법은 무엇입니까?다른 머신이 아직 버전을 업데이트하지 않았다고 해서 시리얼라이제이션(serialization)을 중단하지 않도록 하는 것입니다.

JSON을 버전화하기 위해서는 항상 새 속성을 추가하고 기존 속성을 제거하거나 이름을 바꾸지 않는 것이 중요합니다.는 프로토콜 버퍼가 버전 관리를 처리하는 방식과 유사합니다.

예를 들어, 다음 JSON으로 시작한 경우:

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

이름을 합니다."foo"을 property property로 설정합니다."bar"이름만 바꾸지 마세요.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

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

속성을 삭제하지 않기 때문에 이전 버전을 기반으로 하는 클라이언트는 계속 작동합니다.이 방법의 단점은 시간이 지남에 따라 JSON이 비대해질 수 있으며 오래된 속성을 계속 유지해야 한다는 것입니다.

또, 고객에게 「엣지」의 케이스를 명확하게 정의하는 것도 중요합니다.를 들어, 배열 라고 가정해 ."fooList" . 。"fooList"값을 수 하지 않음되지 않음(오브젝트에 하며 ""로 됩니다).존재하지 않음/정의되지 않음(속성이 물리적으로 JSON 개체에 존재하지 않거나 존재하며 다음과 같이 설정됩니다)."undefined"null빈 , " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "특히 정의되지 않은/늘/빈 경우 클라이언트가 동작 방법을 이해하는 것이 중요합니다.

시멘틱 버전 관리가 어떻게 기능하는지도 읽어보실 것을 권합니다.버전 번호에 시멘틱버전스킴을 도입하면 마이너버전 경계에서 하위 호환성이 있는 변경을 할 수 있지만 메이저버전 경계에서는 변경을 해제할 수 있습니다(클라이언트와 서버 모두 같은 메이저버전에 동의해야 합니다).이것은 JSON 자체의 속성은 아니지만 버전 변경 시 클라이언트가 예상해야 하는 변경 유형을 전달할 때 유용합니다.

Google의 Java 기반 gson 라이브러리는 json에 대한 뛰어난 버전 관리를 지원합니다.만약 당신이 자바 방식을 생각하고 있다면 그것은 매우 편리할 것이다.

여기에는 멋지고 쉬운 튜토리얼이 있습니다.

어떤 시리얼라이징 프로토콜을 사용하든 상관없습니다. 버전 API에 대한 기술은 일반적으로 동일합니다.

일반적으로 필요한 것은 다음과 같습니다.

  1. 소비자가 받아들이는 API 버전을 생산자에게 전달하는 방법(항상 가능한 것은 아니지만)
  2. 제작자가 연속된 데이터에 버전 정보를 포함시키는 방법
  3. 미지의 분야를 다루는 하위 호환 전략

API에서는 되어 있습니다( "API" "API" "API" "Accept" "API" "API" "Accept" "API" "API" "Accept" "API")Accept: application/vnd.myapp-v1+json application/vnd.myapp-v2+json는 사용자가 중 내에서 할 수 있는 들어 API '1'과 '2' 중 하나)를합니다(예: URL '2').https://api.twitter.com/1/statuses/user_timeline.json일반적으로 메이저 버전(즉, 하위 호환성이 없는 변경)에 사용됩니다.서버와 클라이언트에 일치하는 Accept 헤더가 없는 경우 통신은 실패합니다(또는 애플리케이션의 특성에 따라 best effort 방식으로 진행되거나 기본 기준 프로토콜로 폴백됩니다).

으로 프로듀서는 버전 중 이데이터에 삽입합니다를 들어, 「」라고 하는 ).version사용자는 데이터에 포함된 버전 정보를 사용하여 시리얼화된 데이터를 해석하는 방법을 결정해야 합니다.데이터의 버전 정보에는 마이너 버전도 포함되어 있어야 합니다(즉, 하위 호환성이 있는 변경의 경우).일반적으로 소비자는 마이너 버전 정보를 무시하고 데이터를 올바르게 처리할 수 있어야 합니다.단, 마이너 버전을 이해하면 클라이언트는 데이터의 처리 방법에 대해 추가적인 가정을 할 수 있습니다.ssed.

알려지지 않은 필드를 처리하는 일반적인 전략은 HTML 및 CSS의 구문 분석 방법입니다.사용자가 알 수 없는 필드를 발견하면 무시해야 합니다.또한 데이터에 클라이언트가 예상하는 필드가 없을 경우 기본값을 사용해야 합니다.통신의 성격에 따라서는 필수 필드(즉, 누락된 필드가 치명적인 오류로 간주됨)를 지정할 수도 있습니다.마이너 버전에 추가된 필드는 항상 옵션 필드여야 합니다.부 버전에서는 하위 호환성이 있는 한 옵션 필드를 추가하거나 시맨틱 필드를 변경할 수 있습니다.메이저 버전에서는 하위 호환성이 없는 방법으로 필드를 삭제하거나 필수 필드를 추가하거나 시맨틱 필드를 변경할 수 있습니다.

확장 가능한 시리얼라이제이션 형식(JSON이나 XML 등)에서는 데이터는 자기 설명이 필요합니다.즉, 필드명은 항상 데이터와 함께 저장되어야 합니다.특정 위치에서 사용할 수 있는 특정 데이터에 의존해서는 안 됩니다.

이름에서 알 수 있듯이 DataContractJsonSerializer를 사용하지 마십시오. 이 클래스를 통해 처리되는 개체는 다음을 수행해야 합니다.

a) [DataContract]속성과 [DataMember]속성을 표시한다.

b) 정의된 "계약"에 엄격히 준거할 것, 즉 정의된 계약 이상의 것은 없습니다.[ Data Member ]가 추가 또는 누락되면 예외 발생을 위한 역직렬화가 이루어집니다.

충분한 유연성을 원한다면 저렴한 옵션을 원한다면 JavaScript Serializer를 사용하십시오.또는 이 라이브러리를 사용합니다.

http://json.codeplex.com/

이것에 의해, JSON 의 시리얼화를 충분히 제어할 수 있습니다.

초기에 어떤 물체가 있다고 상상해 보세요.

public class Customer
{ 
    public string Name;

    public string LastName;
}

시리얼화되면 다음과 같이 됩니다.

{이름: "John", 성: "Doe"}

필드를 추가/제거하도록 개체 정의를 변경하는 경우.예를 들어 JavaScriptSerializer를 사용하면 역직렬화가 원활하게 수행됩니다.

public class Customer
{ 
    public string Name;

    public string LastName;

    public int Age;
}

마지막 json을 이 새로운 클래스로 디시리얼화하려고 해도 에러는 발생하지 않습니다.중요한 것은 새 필드가 기본값으로 설정된다는 것입니다.이 예에서는 "Age"가 0으로 설정됩니다.

사용자 고유의 규칙에 버전 번호를 포함하는 모든 개체에 있는 필드를 포함할 수 있습니다.이 경우 빈 필드 또는 버전 불일치의 차이를 구별할 수 있습니다.

예를 들어 다음과 같습니다.클래스 Customer v1이 시리얼화되었습니다.

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

Customer v2 인스턴스로 역직렬화하려면 다음과 같은 작업을 수행합니다.

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

오브젝트의 어떤 필드가 신뢰성이 있고 어떤 필드가 신뢰성이 없는지를 검출할 수 있습니다.이 경우 v2 오브젝트인스턴스가 v1 오브젝트인스턴스에서 온 것임을 알 수 있으므로 [Age]필드를 신뢰할 수 없습니다.

"MinVersion" 등의 커스텀 속성도 사용하고 각 필드에 지원되는 최소 버전 번호를 표시해야 합니다.그러면 다음과 같은 결과가 나타납니다.

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

    [MinVersion(1)]
    public string Name;

    [MinVersion(1)]
    public string LastName;

    [MinVersion(2)]
    public int Age;
}

그런 다음 나중에 이 메타데이터에 액세스하여 필요한 작업을 수행할 수 있습니다.

언급URL : https://stackoverflow.com/questions/10042742/what-is-the-best-way-to-handle-versioning-using-json-protocol

반응형