Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

Enrutamiento de solicitudes y vistas

Gabriel edited this page May 21, 2021 · 10 revisions

Documentación:


Foxtrot determina el significado de cada solicitud HTTP mediante la clase enrutador. Existen múltiples clases concretas que realizan el enrutamiento predeterminado:

  • predeterminado Procesa todas las solicitudes al API de Foxtrot y además las solicitudes de vistas y recursos
  • unaPagina Procesa todas las solicitudes al API de Foxtrot y solicitudes de recursos, pero cuando se solicita una vista siempre carga la vista inicial; este enrutador sirve para crear una aplicación de una sola página con vistas embebibles.
  • api Redirige todas las URI a los controladores en lugar de vistas, con el formato /controlador/metodo o /ruta/controlador/metodo. Este enrutador solo admite como otros tipos de solicitudes el acceso a recursos y páginas estáticas (no hay posibilidad de acceder a métodos del controlador de la aplicación, componentes, etc.).

Además, existen diferentes tipos de solicitudes que responden de diferente forma. Estos son (en orden de evaluación):

  • foxtrot Acceso a operaciones del núcleo de Foxtrot (sesion, obtenerVista, noop)
  • recurso URLs de archivos de recursos (CSS, JS)
  • pagina URLs de páginas estáticas (ejemplo /error/)
  • controlador Método del controlador
  • aplicacion Método del controlador principal de la aplicación
  • componente Método de un componente
  • modulo Método de un módulo
  • vista URLs de las vistas

Es posible escribir otros tipos de solicitudes que extiendan solicitud.

Por defecto, se realiza el enrutamiento de la siguiente forma:

Vistas

  • /ruta/a/la/vista se cargará desde aplicaciones/aplicacion/cliente/vistas/ruta/a/la/vista.html o .php

Recursos

  • /recursos/** Se sirve tal cual desde el directorio /recursos
  • /aplicacion/** Se sirve tal cual desde el directorio /aplicaciones/aplicacion (donde aplicacion es el nombre de la aplicación actual)
  • /cliente/** Se sirve tal cual desde el directorio /cliente

Solicitudes

Foxtrot ejecuta automáticamente métodos de diferentes clases, tras estrictas validaciones de seguridad, en base a los valores de distintos parámetros POST como __c, __m, __a, etc.

Desde el cliente, se debe utilizar la clase de servidor, la cual abstrae toda la capa de comunicación. Los controladores y el controlador principal de la aplicación presentan, además, una propiedad servidor (accesible también mediante obtenerServidor()) que redireccionará automáticamente toda llamada a métodos de la misma (this.servidor.metodo()) al controlador PHP correspondiente. Ver Comunicación cliente<->servidor para más información.

Si se está escribiendo un API REST, se debe implementar enrutadorApi o crear un enrutador personalizado que procese las solicitudes, evitando proporcionar al usuario externo URLs que contengan estos parámetros.

Personalizar el enrutamiento

Cada aplicación puede implementar su propia clase extendiendo enrutador o cualquiera de los enrutadores predefinidos para modificar su comportamiento.

El enrutador a utilizar se especifica en el archivo config.php (global o de aplicación), o en la clase configuracion, propiedad enrutador:

configuracion::establecer([
    'enrutador'=>'miEnrutador',
    ...
]);

También es posible definir diferentes bases con diferentes enrutadores estableciendo un array en el parámetro enrutador:

    'enrutador'=>[
        '/api/'=>'api',
        '/'=>'predeterminado'
    ]

Esto último significa que todas las URI con prefijo /api/ serán procesadas por api y cualquier otra URI, por predeterminado.

Notas:

  • El listado debe estar ordenado de la ruta más específica a la menos específica. Es decir que la búsqueda se detendrá ante el primer elemento que coincida con la URI actual.
  • Es posible utilizar expresiones regulares. Cada ruta se compara con el URI mediante una expresión formada por #^, el valor (clave) y #. Por ejemplo: '/api/' sería equivalente a comparar #^/api/#; o /prueba-.+/ a #^/prueba-.+/#.
  • Las rutas se toman completas, es decir, sin remover la base. Por lo tanto, si la base es /api/, debe existir el controlador (público) o el subdirectorio api.
  • Las rutas deben comenzar y finalizar con /.

Por último, enrutador puede ser una función que reciba como parámetros la URI actual y los parámetros, y devuelva la instancia del enrutador.

    'enrutador'=>function($uri,$params) {
        require_once(__DIR__.'/mi-enrutador.php');
        return new \aplicaciones\aplicacion\miEnrutador;
    }

Nota: La URI siempre habrá sido previamente sanitizada y comenzará y finalizará con /.

El valor predeterminado de enrutador es predeterminado.

Enrutador para aplicaciones de una sola página

Cuando se utilice el enrutador enrutadorUnaPagina, todas las solicitudes de vistas serán respondidas con una misma vista (el resto de las solicitudes--recursos, métodos, etc.-- funcionarán normalmente). Para que esto sea posible, debe configurarse la vista a utilizar mediante el método establecerVistaInicio($nombre) del enrutador.

class aplicacion extends \aplicacion {
    function __construct() {
        \foxtrot::obtenerEnrutador()->establecerVistaInicio('inicio');
        ...
    }
    ...
}

Enrutador personalizado por aplicación

Cuando el valor de enrutador difiera de uno de los enrutadores predefinidos, el mismo será buscado en /aplicaciones/aplicacion/servidor. Debe pertenecer al espacio de nombres \aplicaciones\aplicacion\enrutadores (donde aplicacion es el nombre de la aplicación).

Ejemplo:

namespace aplicaciones\miAplicacion\enrutadores;

defined('_inc') or exit;

class miEnrutador extends \enrutadores\predeterminado {
    public function analizar() {
        $uri=$this->obtenerUri(); //La URI ya fue sanitizada y validada, y no no incluye ?

        if($uri=='/mi/metodo/') {
            //Crear una instancia del tipo de recurso 'controlador' que ejecute miControlador::metodo
            $this->fabricarRecurso('controlador')
                ->establecerControlador('mi-controlador')
                ->establecerMetodo('metodo');
            return $this;
        }

        //Continuar el analisis predeterminado
        return parent::analizar();
    }
}
Clone this wiki locally