Projet

Général

Profil

Support #69085

Sur un POST d'API, lever une erreur quand un slash final manque au lieu de rediriger ?

Ajouté par Valentin Deniaud il y a plus d'un an. Mis à jour il y a plus d'un an.

Statut:
Fermé
Priorité:
Normal
Assigné à:
-
Catégorie:
-
Version cible:
-
Début:
14 septembre 2022
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Non
Planning:
Non
Club:
Non

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

Lié à Chrono - Autre #67478: Un PATCH sur /api/agenda/SLUG-DE-LAGENDA/event/SLUG-DE-LEVENEMENT ne retourne pas d'erreurFermé19 juillet 2022

Actions
Lié à Hobo - Development #69409: ajout d'un middleware pour désactiver append_slash sur un POST d'APIFermé21 septembre 2022

Actions

Historique

#1

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é
#2

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)

#3

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.

#4

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
#5

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.

#6

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é
#7

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.

Formats disponibles : Atom PDF