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 ?
Demandes liées
Historique
Mis à jour par Valentin Deniaud il y a plus d'un an
- Lié à Autre #67478: Un PATCH sur /api/agenda/SLUG-DE-LAGENDA/event/SLUG-DE-LEVENEMENT ne retourne pas d'erreur ajouté
Mis à jour par Paul Marillonnet il y a plus d'un an
(À 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)
Mis à jour par Paul Marillonnet il y a plus d'un an
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.
Mis à jour par Benjamin Dauvergne il y a plus d'un an
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
Mis à jour par Paul Marillonnet il y a plus d'un an
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.
Mis à jour par Valentin Deniaud il y a plus d'un an
- Lié à Development #69409: ajout d'un middleware pour désactiver append_slash sur un POST d'API ajouté
Mis à jour par Valentin Deniaud il y a plus d'un an
- Statut changé de Nouveau à Fermé
Merci pour les avis, j'ai ouvert le ticket technique pour mettre ça en place.