Supponiamo che tu abbia una sorta di struttura dati, che viene mantenuta in una sorta di database. Per semplicità, chiamiamo questa struttura dati Person
. Ora hai il compito di progettare un'API CRUD, che consente ad altre applicazioni di creare, leggere, aggiornare ed eliminare Person
s. Per semplicità, supponiamo che questa API sia accessibile tramite una sorta di servizio Web.
Per le parti C, R e D di CRUD, il design è semplice. Userò la notazione funzionale di tipo C # - l'implementazione potrebbe essere SOAP, REST / JSON, o qualcos'altro:
class Person {
string Name;
DateTime? DateOfBirth;
...
}
Identifier CreatePerson(Person);
Person GetPerson(Identifier);
void DeletePerson(Identifier);
E riguardo l'aggiornamento? La cosa naturale da fare sarebbe
void UpdatePerson(Identifier, Person);
ma come specificheresti quali campi di Person
per aggiornare?
Soluzioni che potrei trovare:
-
Potresti sempre richiedere una persona completa da passare, cioè il client farebbe qualcosa del genere per aggiornare la data di nascita:
p = GetPerson(id); p.DateOfBirth = ...; UpdatePerson(id, p);
Tuttavia, ciò richiederebbe una sorta di coerenza transazionale o di blocco tra Get e l'aggiornamento; altrimenti, potresti sovrascrivere qualche altro cambiamento fatto in parallelo da qualche altro client. Ciò renderebbe l'API molto più complicata. Inoltre, è soggetto a errori, dal seguente pseudo-codice (presupponendo una lingua client con supporto JSON)
UpdatePerson(id, { "DateOfBirth": "2015-01-01" });
- che sembra corretto - non cambierebbe solo DateOfBirth ma ripristinerebbe anche tutti gli altri campi su null.
-
Potresti ignorare tutti i campi che sono
null
. Tuttavia, come faresti allora una differenza tra non cambiareDateOfBirth
e modificarlo deliberatamente in null ? -
Cambia la firma in
void UpdatePerson(Identifier, Person, ListOfFieldNamesToUpdate)
. -
Cambia la firma in
void UpdatePerson(Identifier, ListOfFieldValuePairs)
. -
Utilizza alcune funzionalità del protocollo di trasmissione: ad esempio, puoi ignorare tutti i campi non contenuti nella rappresentazione JSON della persona. Tuttavia, di solito è necessario analizzare personalmente il JSON e non essere in grado di utilizzare le funzionalità incorporate della libreria (ad esempio WCF).
Nessuna delle soluzioni sembra davvero elegante per me. Sicuramente, questo è un problema comune, quindi qual è la soluzione best practice utilizzata da tutti?