Rutas

Reglas de Rutas por Defecto

La regla de rutas por defecto de webman es http://127.0.0.1:8787/{controlador}/{acción}.

El controlador por defecto es app\controller\IndexController, y la acción por defecto es index.

Por ejemplo, al acceder a:

  • http://127.0.0.1:8787 se accederá por defecto al método index de la clase app\controller\IndexController
  • http://127.0.0.1:8787/foo se accederá por defecto al método index de la clase app\controller\FooController
  • http://127.0.0.1:8787/foo/test se accederá por defecto al método test de la clase app\controller\FooController
  • http://127.0.0.1:8787/admin/foo/test se accederá por defecto al método test de la clase app\admin\controller\FooController (ver múltiples aplicaciones)

Además, webman a partir de la versión 1.4 soporta reglas de rutas por defecto más complejas, como:

app
├── admin
│   └── v1
│       └── v2
│           └── v3
│               └── controller
│                   └── IndexController.php
└── controller
    ├── v1
    │   └── IndexController.php
    └── v2
        └── v3
            └── IndexController.php

Cuando desee cambiar una ruta de solicitud, modifique el archivo de configuración config/route.php.

Si desea desactivar la ruta por defecto, agregue la siguiente configuración en la última línea del archivo de configuración config/route.php:

Route::disableDefaultRoute();

Rutas de Cierre

Agregue el siguiente código de ruta en config/route.php

use support\Request;
Route::any('/test', function (Request $request) {
    return response('test');
});

Nota
Dado que las funciones de cierre no pertenecen a ningún controlador, $request->app, $request->controller, $request->action estarán todos vacíos.

Cuando se accede a la dirección http://127.0.0.1:8787/test, se devolverá la cadena test.

Nota
La ruta debe comenzar con /, por ejemplo:

use support\Request;
// Uso incorrecto
Route::any('test', function (Request $request) {
    return response('test');
});

// Uso correcto
Route::any('/test', function (Request $request) {
    return response('test');
});

Rutas de Clase

Agregue el siguiente código de ruta en config/route.php

Route::any('/testclass', [app\controller\IndexController::class, 'test']);

Cuando se accede a la dirección http://127.0.0.1:8787/testclass, se devolverá el valor de retorno del método test de la clase app\controller\IndexController.

Parámetros de Ruta

Si hay parámetros en la ruta, se pueden coincidir con {key}, y los resultados coincidentes se pasarán a los parámetros del método del controlador correspondiente (a partir del segundo parámetro en adelante), por ejemplo:

// Coincide con /user/123 /user/abc
Route::any('/user/{id}', [app\controller\UserController::class, 'get']);
namespace app\controller;
use support\Request;

class UserController
{
    public function get(Request $request, $id)
    {
        return response('Recibido el parámetro'.$id);
    }
}

Más ejemplos:

use support\Request;
// Coincide con /user/123, no coincide con /user/abc
Route::any('/user/{id:\d+}', function (Request $request, $id) {
    return response($id);
});

// Coincide con /user/foobar, no coincide con /user/foo/bar
Route::any('/user/{name}', function (Request $request, $name) {
   return response($name);
});

// Coincide con /user /user/123 y /user/abc   [] indica opcional
Route::any('/user[/{name}]', function (Request $request, $name = null) {
   return response($name ?? 'tom');
});

// Coincide con cualquier solicitud que tenga /user/ como prefijo
Route::any('/user/[{path:.+}]', function (Request $request) {
    return $request->path();
});

// Coincide con todas las solicitudes options   : seguido de la expresión regular, indica la regla de expresión regular de este parámetro nombrado
Route::options('[{path:.+}]', function () {
    return response('');
});

Resumen del uso avanzado:

[] La sintaxis en las rutas de Webman se utiliza principalmente para manejar partes de ruta opcionales o coincidir rutas dinámicas, permitiendo definir estructuras de ruta más complejas y reglas de coincidencia.

: se utiliza para especificar expresiones regulares.

Agrupación de Rutas

A veces, las rutas contienen una gran cantidad de prefijos comunes, en este caso, podemos usar la agrupación de rutas para simplificar la definición. Por ejemplo:

Route::group('/blog', function () {
   Route::any('/create', function (Request $request) {return response('crear');});
   Route::any('/edit', function (Request $request) {return response('editar');});
   Route::any('/view/{id}', function (Request $request, $id) {return response("ver $id");});
});

Equivale a

Route::any('/blog/create', function (Request $request) {return response('crear');});
Route::any('/blog/edit', function (Request $request) {return response('editar');});
Route::any('/blog/view/{id}', function (Request $request, $id) {return response("ver $id");});

Uso de agrupación anidada

Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('crear');});
      Route::any('/edit', function (Request $request) {return response('editar');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("ver $id");});
   });  
});

Middleware de Rutas

Podemos asignar middleware a una ruta o a un grupo de rutas.
Por ejemplo:

Route::any('/admin', [app\admin\controller\IndexController::class, 'index'])->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

Route::group('/blog', function () {
   Route::any('/create', function () {return response('crear');});
   Route::any('/edit', function () {return response('editar');});
   Route::any('/view/{id}', function ($request, $id) {return response("ver $id");});
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# Ejemplo de uso incorrecto (este uso es efectivo cuando webman-framework >= 1.5.7)
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('crear');});
      Route::any('/edit', function (Request $request) {return response('editar');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("ver $id");});
   });  
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);
# Ejemplo de uso correcto
Route::group('/blog', function () {
   Route::group('/v1', function () {
      Route::any('/create', function (Request $request) {return response('crear');});
      Route::any('/edit', function (Request $request) {return response('editar');});
      Route::any('/view/{id}', function (Request $request, $id) {return response("ver $id");});
   })->middleware([
        app\middleware\MiddlewareA::class,
        app\middleware\MiddlewareB::class,
    ]);  
});

Rutas de Recursos

Route::resource('/test', app\controller\IndexController::class);

// Especificar rutas de recursos
Route::resource('/test', app\controller\IndexController::class, ['index','create']);

// Rutas de recursos no definidas
// Como notify, la dirección de acceso será una ruta any /test/notify o /test/notify/{id}, el routeName será test.notify
Route::resource('/test', app\controller\IndexController::class, ['index','create','notify']);
Verbo URI Acción Nombre de Ruta
GET /test index test.index
GET /test/create create test.create
POST /test store test.store
GET /test/{id} show test.show
GET /test/{id}/edit edit test.edit
PUT /test/{id} update test.update
DELETE /test/{id} destroy test.destroy
PUT /test/{id}/recovery recovery test.recovery

Generación de URLs

Nota
Actualmente no se soporta la generación de URLs para rutas con agrupaciones anidadas.

Por ejemplo, la ruta:

Route::any('/blog/{id}', [app\controller\BlogController::class, 'view'])->name('blog.view');

Podemos usar el siguiente método para generar la URL de esta ruta.

route('blog.view', ['id' => 100]); // El resultado será /blog/100

Al usar la URL de una ruta en la vista, puedes utilizar este método, de modo que independientemente de cómo cambien las reglas de ruta, la URL se generará automáticamente, evitando una gran cantidad de cambios en los archivos de vista debido a ajustes en las direcciones de ruta.

Obtener Información de la Ruta

A través del objeto $request->route podemos obtener información de la ruta de la solicitud actual, por ejemplo:

$route = $request->route; // Equivalente a $route = request()->route;
if ($route) {
    var_export($route->getPath());
    var_export($route->getMethods());
    var_export($route->getName());
    var_export($route->getMiddleware());
    var_export($route->getCallback());
    var_export($route->param());
}

Nota
Si la solicitud actual no coincide con ninguna ruta configurada en config/route.php, entonces $request->route será nulo, es decir, al utilizar la ruta por defecto, $request->route será nulo.

Manejo de 404

Cuando una ruta no se encuentra, devuelve por defecto un estado 404 y muestra el contenido relacionado con 404.

Si el desarrollador desea intervenir en el flujo de negocio cuando no se encuentra una ruta, puede usar la ruta de retroceso que webman proporciona mediante el método Route::fallback($callback). Por ejemplo, el siguiente código redirige a la página de inicio cuando no se encuentra la ruta.

Route::fallback(function(){
    return redirect('/');
});

Además, cuando la ruta no existe, se puede devolver un JSON, lo cual es muy útil cuando webman se utiliza como una interfaz API.

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 no encontrado']);
});

Agregar Middleware a 404

Las solicitudes de 404 por defecto no pasan por ningún middleware, si se necesita agregar middleware a las solicitudes de 404, consulte el siguiente código.

Route::fallback(function(){
    return json(['code' => 404, 'msg' => '404 no encontrado']);
})->middleware([
    app\middleware\MiddlewareA::class,
    app\middleware\MiddlewareB::class,
]);

Enlace relacionado Página de error 404 500 personalizada

Desactivar Rutas por Defecto

// Desactivar las rutas por defecto del proyecto principal, sin afectar a los plugins de aplicaciones
Route::disableDefaultRoute();
// Desactivar las rutas de la aplicación admin del proyecto principal, sin afectar a los plugins de aplicaciones
Route::disableDefaultRoute('', 'admin');
// Desactivar las rutas por defecto del plugin foo, sin afectar al proyecto principal
Route::disableDefaultRoute('foo');
// Desactivar las rutas por defecto de la aplicación admin del plugin foo, sin afectar al proyecto principal
Route::disableDefaultRoute('foo', 'admin');
// Desactivar la ruta por defecto de [\app\controller\IndexController::class, 'index']
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);

Desactivar Rutas por Defecto con Anotaciones

Podemos desactivar las rutas por defecto de un controlador específico mediante anotaciones, por ejemplo:

namespace app\controller;
use support\annotation\DisableDefaultRoute;

#[DisableDefaultRoute]
class IndexController
{
    public function index()
    {
        return 'index';
    }
}

Igualmente, podemos desactivar las rutas por defecto de un controlador específico a través de una anotación, por ejemplo:

namespace app\controller;
use support\annotation\DisableDefaultRoute;

class IndexController
{
    #[DisableDefaultRoute]
    public function index()
    {
        return 'index';
    }
}

Interfaz de Rutas

// Establecer la ruta para cualquier método de solicitud para $uri
Route::any($uri, $callback);
// Establecer la ruta para solicitudes GET para $uri
Route::get($uri, $callback);
// Establecer la ruta para solicitudes POST para $uri
Route::post($uri, $callback);
// Establecer la ruta para solicitudes PUT para $uri
Route::put($uri, $callback);
// Establecer la ruta para solicitudes PATCH para $uri
Route::patch($uri, $callback);
// Establecer la ruta para solicitudes DELETE para $uri
Route::delete($uri, $callback);
// Establecer la ruta para solicitudes HEAD para $uri
Route::head($uri, $callback);
// Establecer la ruta para solicitudes OPTIONS para $uri
Route::options($uri, $callback);
// Establecer múltiples tipos de solicitudes para la misma ruta
Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
// Agrupación de rutas
Route::group($path, $callback);
// Rutas de recursos
Route::resource($path, $callback, [$options]);
// Desactivar rutas
Route::disableDefaultRoute($plugin = '');
// Ruta de retroceso, establecer la ruta por defecto
Route::fallback($callback, $plugin = '');
// Obtener información de todas las rutas
Route::getRoutes();

Si uri no tiene una ruta correspondiente (incluyendo la ruta por defecto), y la ruta de retroceso no está configurada, se devolverá un 404.

Múltiples Archivos de Configuración de Rutas

Si desea gestionar rutas a través de múltiples archivos de configuración, por ejemplo, en múltiples aplicaciones donde cada aplicación tiene su propia configuración de rutas, puede requerir archivos externos de la siguiente manera.
Por ejemplo, en config/route.php

<?php

// Cargar la configuración de rutas para la aplicación admin
require_once app_path('admin/config/route.php');
// Cargar la configuración de rutas para la aplicación api
require_once app_path('api/config/route.php');