Estamos usando Werkzeug y Flask para crear una API REST. En este contexto, no queremos el comportamiento automático de agregar barras inclinadas, ya que esto conduce a asimetrías entre los GET y otras solicitudes, y es aceptable ser estricto aquí.
Actualmente, necesitamos usar una clase de regla personalizada que se conecte a los componentes internos ( Rule.match
y RequestSlash
) para hacer esto.
¿Tendría sentido agregar esto como una opción de configuración de primer orden? ¿Algo como append_slash
(para poner en paralelo la opción equivalente de Django) en mapas de URL?
app.url_map.strict_slashes = False
es todo lo que necesita para evitar esto.
Eso realmente hace que la ruta coincida cuando falta la barra. Lo quiero en 404.
El comportamiento actual es:
| La regla tiene barra inclinada al final | La ruta tiene una barra al final | strict_slashes
| Resultado |
| - | - | - | - |
| N | N | True
| (partido) |
| N | N | False
| (partido) |
| N | Y | True
| 404 |
| N | Y | False
| 404 |
| Y | N | True
| 301 |
| Y | N | False
| (partido) |
| Y | Y | True
| (partido) |
| Y | Y | False
| (partido) |
Quiero un 404 cuando la regla tiene una barra al final pero la ruta no. Ahora mismo estoy haciendo esto a través de:
class StrictRule(Rule):
def match(self, path, method=None):
try:
result = super(StrictRule, self).match(path, method)
except RequestSlash:
return None
return result
Pero prefiero no meter la mano en el interior.
Usar la regla personalizada sería la forma correcta de hacer esto en Flask. Hemos decidido internamente no intentar crear todo para todos en reglas. Si desea una regla más allá de lo que se ofrece como estándar, deberá especificarla. Para Flash, establecería url_rule_class
en la nueva clase. Consulte los documentos de Flask para obtener más información. http://flask.pocoo.org/docs/1.0/api/?highlight=rule#flask.Flask.url_rule_class
@aenglander
Según https://github.com/pallets/werkzeug/issues/1246#issuecomment -362099342, el problema aquí es con la implementación de la regla personalizada. RequestSlash
está explícitamente marcado como una excepción interna por https://github.com/pallets/werkzeug/blob/a220671d66755a94630a212378754bb432811158/src/werkzeug/routing.py#L259 -L260, por lo que es bastante incómodo manejar esto en codigo de usuario.
Y aunque ciertamente estoy de acuerdo en que las reglas base no deberían admitir todos los casos de uso posibles, no coincidir en una barra inclinada ausente es un caso de uso muy común. Para la técnica anterior, este patrón es uno de los pocos que se exponen explícitamente en la configuración de Django a través de APPEND_SLASH
: https://docs.djangoproject.com/en/dev/ref/settings/#append -slash.
"Interno" en este caso significa "manejado internamente", no "solo para uso interno". El código que ha mostrado está bien para usar.
@davidism Gracias por la aclaración. Entonces seguiré adelante y seguiré con esto.
Comentario más útil
app.url_map.strict_slashes = False
es todo lo que necesita para evitar esto.