Disons que vous avez une sorte de structure de données, qui est persistante dans une sorte de base de données. Pour simplifier, appelons cette structure de données Person
. Vous êtes maintenant chargé de concevoir une API CRUD, qui permet à d'autres applications de créer, lire, mettre à jour et supprimer des Person
s. Pour simplifier, supposons que cette API soit accessible via une sorte de service Web.
Pour les parties C, R et D de CRUD, la conception est simple. J'utiliserai une notation fonctionnelle de type C # - l'implémentation pourrait être SOAP, REST / JSON, ou autre chose:
class Person {
string Name;
DateTime? DateOfBirth;
...
}
Identifier CreatePerson(Person);
Person GetPerson(Identifier);
void DeletePerson(Identifier);
Et la mise à jour? La chose naturelle à faire serait
void UpdatePerson(Identifier, Person);
mais comment voulez - vous préciser que les champs de Person
la mise à jour?
Solutions que je pourrais trouver:
Vous pourriez toujours exiger qu'une personne complète soit transmise, c'est-à-dire que le client ferait quelque chose comme ça pour mettre à jour la date de naissance:
p = GetPerson(id); p.DateOfBirth = ...; UpdatePerson(id, p);
Cependant, cela nécessiterait une sorte de cohérence transactionnelle ou de verrouillage entre le Get et la mise à jour; sinon, vous pourriez remplacer une autre modification effectuée en parallèle par un autre client. Cela rendrait l'API beaucoup plus compliquée. De plus, il est sujet aux erreurs, car le pseudo-code suivant (en supposant une langue client avec le support JSON)
UpdatePerson(id, { "DateOfBirth": "2015-01-01" });
- qui semble correct - non seulement changerait DateOfBirth mais réinitialiserait également tous les autres champs à null.
Vous pouvez ignorer tous les champs qui le sont
null
. Cependant, comment feriez-vous alors une différence entre ne pas le changerDateOfBirth
et le changer délibérément en null ?Modifiez la signature en
void UpdatePerson(Identifier, Person, ListOfFieldNamesToUpdate)
.Modifiez la signature en
void UpdatePerson(Identifier, ListOfFieldValuePairs)
.Utilisez une fonction du protocole de transmission: Par exemple, vous pouvez ignorer tous les champs non contenus dans la représentation JSON de la personne. Cependant, cela nécessite généralement d'analyser le JSON vous-même et de ne pas pouvoir utiliser les fonctionnalités intégrées de votre bibliothèque (par exemple WCF).
Aucune des solutions ne me semble vraiment élégante. C'est sûrement un problème courant, alors quelle est la solution de meilleure pratique utilisée par tout le monde?
Person
instances nouvellement créées qui ne sont toujours pas persistantes, et dans le cas où l'identifiant est décidé dans le cadre du mécanisme de persistance, laissez-le simplement à null. Quant à la réponse, JPA utilise un numéro de version; si vous lisez la version 23, lorsque vous mettez à jour l'élément si la version dans DB est 24, l'écriture échoue.