¿Cómo hacer rutas dinámicas en Phoenix y Plug?

Cuando se declaran las rutas en un router de Plug o de Phoenix es posible indicar rutas dinámicas si se utilizan símbolos como el dos puntos o el asterisco. Por ejemplo, /users/:id o /file/*path. En este tutorial exploramos el funcionamiento de este tipo de parámetros de ruta, vemos cómo capturarlos como variable en Plug para poder usarlos luego en nuestros códigos y también cómo afectan los prefijos y sufijos a la manera en la que se decodifica una de estas rutas.

Cuando trabajamos con Elixir y sus frameworks web como Plug y Phoenix, uno de los aspectos fundamentales es el manejo de rutas dinámicas. Aunque en este caso nos centraremos en Plug, todo lo que veremos es aplicable a Phoenix, ya que este último utiliza Plug internamente para gestionar las rutas.

Al iniciar un servidor web con Plug, este se encarga de comparar la ruta que visitamos con las rutas que hemos declarado en nuestro router. Por ejemplo, si tenemos una ruta definida como get "/saludar", al visitar esa URL se ejecutará el código asociado. Si añadimos otra ruta como get "/saludar/Dani", esta se activará cuando accedamos a esa ruta específica.

Sin embargo, si queremos manejar saludos personalizados para muchas personas, no es práctico definir una ruta para cada nombre. Aquí es donde entran en juego las rutas dinámicas. Podemos definir una ruta con un parámetro dinámico usando el símbolo dos puntos : seguido del nombre de la variable que queremos capturar. Por ejemplo, la ruta get "/saludar/:persona" capturará cualquier valor que venga después de /saludar/ y lo almacenará en la variable persona.

Esto funciona de manera similar al pattern matching que conocemos en Elixir, pero aplicado a las cadenas de texto que forman las rutas. Así, si visitamos /saludar/paula, la variable persona tendrá el valor "paula". Lo interesante es que esta variable puede contener cualquier cadena que no incluya una barra /, por lo que nombres con números, puntos o guiones también serán capturados sin problema.

Además, podemos definir rutas con múltiples parámetros dinámicos. Por ejemplo, una ruta como /api/v1/empleados/:nombre/ofertas/:id capturará tanto el nombre del empleado como el id de la oferta. Es importante recordar que, aunque el parámetro id pueda representar un número, siempre se capturará como una cadena, por lo que si necesitamos trabajar con él como número, deberemos convertirlo explícitamente.

También podemos combinar variables dinámicas con prefijos o sufijos en la ruta. Por ejemplo, si queremos capturar la versión de una API que siempre empieza con una v, podemos definir la ruta como /api/v:version, donde version capturará el número o cadena que siga a la v. Esto nos permite validar que la ruta tenga un formato específico, ya que si el prefijo no coincide, la ruta no será considerada válida.

En cuanto a sufijos, podemos hacer algo similar. Por ejemplo, si definimos una ruta como /saludar/:persona.gritar, podemos capturar la variable persona siempre que la ruta termine con .gritar. Esto nos permite aplicar transformaciones específicas, como convertir el saludo a mayúsculas. Sin embargo, hay que tener en cuenta que el orden en que definimos las rutas es crucial. Las rutas más específicas deben ir antes que las más generales para que el sistema de matching funcione correctamente y no se ejecute una ruta menos específica antes que la que realmente queremos.

Finalmente, existe una forma de capturar rutas completas o globs usando el operador asterisco *. Por ejemplo, si definimos una ruta como /hola/*todo, la variable todo capturará todos los segmentos restantes de la ruta como una lista de cadenas. Esto es especialmente útil cuando queremos manejar rutas con una estructura variable o anidada, como directorios y archivos en un sistema de archivos virtual.

Este mecanismo nos permite construir aplicaciones web muy flexibles, donde podemos capturar y procesar rutas dinámicas con parámetros, prefijos, sufijos y rutas completas, todo ello manteniendo un código limpio y organizado. Además, dado que Phoenix utiliza Plug para el manejo de rutas, todo lo que hemos visto es directamente aplicable en ese framework, permitiéndonos definir rutas dinámicas que se dirijan a controladores o que hagan forwards a otros módulos según nuestras necesidades.

Lista de reproducción
  1. 1
    mix
    10 minutos
  2. 2
    Documentando código: comentarios, docs y moduledocs
    10 minutos
  3. 3
    Atributos de módulo
    9 minutos
  4. 4
    Dependencias
    12 minutos
  5. 5
    Un ejemplo práctico de módulo útil
    13 minutos
  6. 6
    Alias e import
    10 minutos
  7. 7
    Sobre las macros, require y use
    11 minutos
  8. 8
    Typespecs (parte 1, usando tipos básicos)
    10 minutos
  9. 9
    Typespecs (parte 2, tipos propios y t())
    11 minutos
  10. 10
    Comportamientos
    11 minutos
  11. 11
    Tratamiento de errores con rescue
    8 minutos
  12. 12
    Elevando errores con raise
    8 minutos
  13. 13
    with
    14 minutos
  14. 14
    Sigilos
    8 minutos
  15. 15
    Tests con ExUnit
    12 minutos
  16. 16
    Más particularidades de ExUnit
    13 minutos
  17. 17
    Microservicios en Elixir con Plug
    11 minutos
  18. 18
    Cómo Plug.Router te ayuda a escribir microservicios en Elixir
    14 minutos
  19. 19
    ¿Cómo hacer rutas dinámicas en Phoenix y Plug?
    13 minutos