D'après mes connaissances :
-
PUT
- mettre à jour l'objet avec sa représentation complète (remplacer) -
PATCH
- mettre à jour l'objet avec seulement les champs donnés (update)
J'utilise Spring pour implémenter un serveur HTTP assez simple. Lorsqu'un utilisateur veut mettre à jour ses données, il doit faire une requête HTTP PATCH
vers un certain point final (disons : api/user
). Le corps de sa demande est mappé à un DTO via @RequestBody
qui ressemble à ceci :
class PatchUserRequest {
@Email
@Length(min = 5, max = 50)
var email: String? = null
@Length(max = 100)
var name: String? = null
...
}
Ensuite, j'utilise un objet de cette classe pour mettre à jour (patcher) l'objet utilisateur :
fun patchWithRequest(userRequest: PatchUserRequest) {
if (!userRequest.email.isNullOrEmpty()) {
email = userRequest.email!!
}
if (!userRequest.name.isNullOrEmpty()) {
name = userRequest.name
}
...
}
Mon doute est le suivant : que se passe-t-il si un client (une application web par exemple) souhaite effacer une propriété ? Je ne tiendrais pas compte d'une telle modification.
Comment puis-je savoir si un utilisateur a voulu effacer une propriété (il m'a envoyé intentionnellement une propriété nulle) ou s'il ne veut tout simplement pas la modifier ? Dans les deux cas, la propriété sera nulle dans mon objet.
Je vois deux options ici :
- Convenez avec le client que s'il veut supprimer une propriété, il doit m'envoyer une chaîne de caractères vide (mais qu'en est-il des dates et des autres types de chaînes de caractères ?)
- Arrêtez d'utiliser le mappage DTO et utilisez une simple carte, qui me permettra de vérifier si un champ a été donné vide ou pas donné du tout. Qu'en est-il de la validation du corps de la requête ? J'utilise
@Valid
en ce moment.
Comment traiter correctement de tels cas, en harmonie avec REST et toutes les bonnes pratiques ?
EDIT :
On pourrait dire que PATCH
ne devrait pas être utilisé dans un tel exemple et je devrais utiliser PUT
pour mettre à jour mon utilisateur. Mais qu'en est-il des mises à jour de l'API (ajout d'une nouvelle propriété par exemple) ? Il faudrait que je fasse une version de mon API (ou une version du point d'accès utilisateur seul) après chaque changement d'utilisateur, api/v1/user
qui accepte PUT
avec un ancien corps de demande, api/v2/user
qui accepte PUT
avec un nouveau corps de demande, etc. Je suppose que ce n'est pas la solution et PATCH
existe pour une raison.