Support #69085
Sur un POST d'API, lever une erreur quand un slash final manque au lieu de rediriger ?
0%
Description
La plupart de nos API sur les briques Django prennent un / final.
On a le setting Django APPEND_SLASH à True (valeur par défaut, https://docs.djangoproject.com/en/4.1/ref/settings/#append-slash), qui fait que si on appelle une URL en oubliant le / final, il y a redirection vers la bonne URL avec le /.
C'est très bien en front ou pour les API qui s'appellent via GET.
Par contre en POST/PATCH/PUT, la redirection se fait et on perd les données, donc on se retrouve à avoir un appel qui semble fonctionner et en fait pas du tout (voir ticket lié).
Est-ce qu'on écrirait pas un bout de middleware qui si le chemin commence par api
, renvoie une erreur JSON informant qu'il manque le slash final ?
Related issues
History
Updated by Valentin Deniaud about 2 years ago
- Related to Autre #67478: Un PATCH sur /api/agenda/SLUG-DE-LAGENDA/event/SLUG-DE-LEVENEMENT ne retourne pas d'erreur added
Updated by Paul Marillonnet about 2 years ago
(À noter que si on estime que c’est pas grave que l’ajout automatique du slash final n’ait pas lieu sur toutes les api quel que soit le verbe http, et que si le problème peut attendre qu’on ait django 3.2 partout, alors on peut décorer les vues d’api de façon à les exclure de la conf globale APPEND_SLASH : https://docs.djangoproject.com/en/3.2/topics/http/decorators/#django.views.decorators.common.no_append_slash)
Updated by Paul Marillonnet about 2 years ago
Paul Marillonnet a écrit :
(À noter que si on estime que c’est pas grave que l’ajout automatique du slash final n’ait pas lieu sur toutes les api quel que soit le verbe http, et que si le problème peut attendre qu’on ait django 3.2 partout, alors on peut décorer les vues d’api de façon à les exclure de la conf globale APPEND_SLASH : https://docs.djangoproject.com/en/3.2/topics/http/decorators/#django.views.decorators.common.no_append_slash)
Mais bien sûr ça va péter des appels GET existants, on oublie.
Updated by Benjamin Dauvergne about 2 years ago
Paul Marillonnet a écrit :
(À noter que si on estime que c’est pas grave que l’ajout automatique du slash final n’ait pas lieu sur toutes les api quel que soit le verbe http, et que si le problème peut attendre qu’on ait django 3.2 partout, alors on peut décorer les vues d’api de façon à les exclure de la conf globale APPEND_SLASH : https://docs.djangoproject.com/en/3.2/topics/http/decorators/#django.views.decorators.common.no_append_slash)
C'est tout simplement plus simple de dériver de CommonMiddleware:
from django.middleware.common import CommonMiddleware
class APICommonMiddleware(BaseCommonMiddleware):
def process_request(self, request):
response = super().process_request(request)
if response and self.should_redirect_with_slash(request) and request.path_info.startswith('/api/') and request.method != 'GET':
return JsonResponse({'err': 1, 'err_desc': 'add a slash'}, status=404)
return response
def process_response(self, request, response):
response_is_404 = (response.status_code == 404)
response = super().process_response(request, response)
if response_is_404 and isinstance(response, self.response_redirect_class) and self.should_redirect_with_slash(request) and request.path_info.startswith('/api/') and request.method != 'GET':
return JsonResponse({'err': 1, 'err_desc': 'add a slash'}, status=404)
return response
Updated by Paul Marillonnet about 2 years ago
Benjamin Dauvergne a écrit :
C'est tout simplement plus simple de dériver de CommonMiddleware:
Oui j’étais juste pas fan du traitement du slash final manquant qui varie selon le verbe qu’on envoie, mais comme il y a forcément ici et là des appels GET en place avec le slash manquant, on n’a pas tellement le choix. Pas de meilleure solution à proposer que celle de Valentin et toi, elle me va si elle peut prévenir les appels qui font semblant de fonctionner.
Updated by Valentin Deniaud about 2 years ago
- Related to Développement #69409: ajout d'un middleware pour désactiver append_slash sur un POST d'API added
Updated by Valentin Deniaud about 2 years ago
- Status changed from Nouveau to Fermé
Merci pour les avis, j'ai ouvert le ticket technique pour mettre ça en place.