Essayer de faire évoluer (pas de ré-implémenter) les services existants
Pour la gestion des versions, vous allez être dans un monde de mal si vous essayez de maintenir différents types statiques pour les différentes version d'extrémité. Nous avons d'abord commencé en bas de cette route, mais dès que vous commencez à l'appui de votre première version de l'effort de développement afin de maintenir de multiples versions d'un même service explose car vous en aurez besoin pour maintenir manuel de la cartographie des différents types de facilement les fuites en avoir plusieurs implémentations parallèles, chacun couplé à une les différentes versions de type une violation massive de la SEC. C'est moins un problème pour les langages dynamiques où les mêmes modèles peuvent facilement être ré-utilisés par les différentes versions.
Profitez de gestion des versions dans sérialiseurs
Ma recommandation est de ne pas explicitement version, mais de tirer avantage de la gestion des versions des capacités à l'intérieur de l'formats de sérialisation.
E. g: vous n'avez généralement pas besoin de s'inquiéter à propos du contrôle de version avec JSON clients comme la gestion des versions des capacités de l' JSON et JSV Sérialiseurs sont bien plus résistants.
Améliorer vos services existants sur la défensive
Avec XML et DataContract vous pouvez facilement ajouter et supprimer des champs sans faire une modification de rupture. Si vous ajoutez IExtensibleDataObject
pour votre réponse DTO est vous avez également un potentiel pour accéder à des données qui n'est pas défini sur la DTO. Mon approche de la gestion des versions est au programme, sur la défensive, afin de ne pas introduire une modification de rupture, vous pouvez vérifier que c'est le cas avec les tests d'Intégration à l'aide de vieux Otd. Voici quelques conseils que j'ai suivi:
- Ne pas changer le type d'une propriété existante - Si vous avez besoin d'un autre type d'ajouter un autre à la propriété et à l'utilisation de l'ancien/existante pour déterminer la version
- Programme défensivement réaliser ce que les propriétés n'existent pas avec les anciens clients afin de ne pas la rendre obligatoire.
- Garder un seul espace de noms global (uniquement pour les XML/SOAP extrémités)
- Je le faire en utilisant le [assemblée] attribut dans la AssemblyInfo.cs de chacun de vos DTO projets:
[assembly: ContractNamespace("http://schemas.servicestack.net/types",
ClrNamespace = "MyServiceModel.DtoTypes")]
L'assemblée attribut vous permet d'économiser de la main à la spécification des espaces de noms explicites sur chaque DTO, j'.e:
namespace MyServiceModel.DtoTypes {
[DataContract(Namespace="http://schemas.servicestack.net/types")]
public class Foo { .. }
}
Si vous souhaitez utiliser un autre espace de noms XML de la valeur par défaut ci-dessus, vous devez l'enregistrer auprès de:
SetConfig(new EndpointHostConfig {
WsdlServiceNamespace = "http://schemas.my.org/types"
});
L'incorporation de gestion des versions dans les Dto
La plupart du temps, si vous programmez sur la défensive et de faire évoluer vos services normalement vous n'aurez pas besoin de savoir exactement quelle est la version d'un client spécifique est de l'aide que vous pouvez déduire à partir des données qui est rempli. Mais dans les rares cas de vos besoins en matière de services de tordre le comportement basé sur la version spécifique du client, vous pouvez incorporer des informations de version dans votre Otd.
Avec la première version de votre Otd vous publiez, vous pouvez heureusement les créer sans aucune pensée de versioning.
class Foo {
string Name;
}
Mais peut-être que pour une raison quelconque, la Forme/UI a été changé, et vous ne vouliez plus le Client à utiliser le ambiguë Nom de la variable et vous aussi voulu suivre la version spécifique du client à l'aide de:
class Foo {
Foo() {
Version = 1;
}
int Version;
string Name;
string DisplayName;
int Age;
}
Plus tard, il a été discuté dans une réunion d'Équipe, DisplayName n'était pas assez bon et vous devez les diviser en différents domaines:
class Foo {
Foo() {
Version = 2;
}
int Version;
string Name;
string DisplayName;
string FirstName;
string LastName;
DateTime? DateOfBirth;
}
Donc l'état actuel, c'est que vous avez 3 différentes versions de client, avec les appels existants qui ressemblent à:
la Version 1:
client.Post(new Foo { Name = "Foo Bar" });
sortie de la v2:
client.Post(new Foo { Name="Bar", DisplayName="Foo Bar", Age=18 });
v3 Version:
client.Post(new Foo { FirstName = "Foo", LastName = "Bar",
DateOfBirth = new DateTime(1994, 01, 01) });
Vous pouvez continuer à gérer ces différentes versions de la même application (qui sera à l'aide de la dernière v3 version de l'Otd) e.g:
class FooService : Service {
public object Post(Foo request) {
//v1:
request.Version == 0
request.Name == "Foo"
request.DisplayName == null
request.Age = 0
request.DateOfBirth = null
//v2:
request.Version == 2
request.Name == null
request.DisplayName == "Foo Bar"
request.Age = 18
request.DateOfBirth = null
//v3:
request.Version == 3
request.Name == null
request.DisplayName == null
request.FirstName == "Foo"
request.LastName == "Bar"
request.Age = 0
request.DateOfBirth = new DateTime(1994, 01, 01)
}
}