Rotas
Regras de roteamento padrão
A regra de roteamento padrão do webman é http://127.0.0.1:8787/{controlador}/{ação}.
O controlador padrão é app\controller\IndexController e a ação padrão é index.
Por exemplo, ao acessar:
http://127.0.0.1:8787irá acessar por padrão o métodoindexda classeapp\controller\IndexControllerhttp://127.0.0.1:8787/fooirá acessar por padrão o métodoindexda classeapp\controller\FooControllerhttp://127.0.0.1:8787/foo/testirá acessar por padrão o métodotestda classeapp\controller\FooControllerhttp://127.0.0.1:8787/admin/foo/testirá acessar por padrão o métodotestda classeapp\admin\controller\FooController(consulte Multiaplicação)
Além disso, a partir da versão 1.4, o webman suporta regras de roteamento padrão mais complexas, por exemplo
app
├── admin
│ └── v1
│ └── v2
│ └── v3
│ └── controller
│ └── IndexController.php
└── controller
├── v1
│ └── IndexController.php
└── v2
└── v3
└── IndexController.php
Ao querer alterar o roteamento de uma solicitação, altere o arquivo de configuração config/route.php.
Se você deseja desativar o roteamento padrão, adicione a seguinte configuração na última linha do arquivo de configuração config/route.php:
Route::disableDefaultRoute();
Rota fechada
Adicione o seguinte código de rota ao arquivo config/route.php
use support\Request;
Route::any('/test', function (Request $request) {
return response('test');
});
Nota
Como a função fechada não pertence a nenhum controlador,$request->app,$request->controllere$request->actionserão todos strings vazias.
Ao acessar o endereço http://127.0.0.1:8787/test, será retornado o string "test".
Nota
O caminho da rota deve começar com/, por exemplo
use support\Request;
// Uso incorreto
Route::any('test', function (Request $request) {
return response('test');
});
// Uso correto
Route::any('/test', function (Request $request) {
return response('test');
});
Rota da classe
Adicione o seguinte código de rota ao arquivo config/route.php
Route::any('/testclass', [app\controller\IndexController::class, 'test']);
Ao acessar o endereço http://127.0.0.1:8787/testclass, será retornado o valor de retorno do método test da classe app\controller\IndexController.
Roteamento por anotações
Defina rotas através de anotações nos métodos do controlador, sem necessidade de configurar em config/route.php.
Nota
Esta funcionalidade requer webman-framework >= v2.2.0
Uso básico
namespace app\controller;
use support\annotation\route\DisableDefaultRoute;
use support\annotation\route\Get;
use support\annotation\route\Post;
use support\annotation\route\Route;
#[DisableDefaultRoute]
class UserController
{
#[Get('/user/{id}')]
public function show($id)
{
return "user $id";
}
#[Post('/user')]
public function store()
{
return 'created';
}
#[Route('/user/form', ['GET', 'POST'], 'user.form')]
public function form()
{
return 'form';
}
}
Anotações disponíveis: #[Get] #[Post] #[Put] #[Delete] #[Patch] #[Head] #[Options] #[Any] (qualquer método). O caminho deve começar com /. O segundo parâmetro pode especificar o nome da rota, usado por route() para gerar URL.
#[DisableDefaultRoute] desativa o roteamento padrão do controlador (opcional); apenas rotas definidas por anotações são acessíveis.
Sintaxe completa #[Route]: #[Route(path, methods, name)]
path: caminho da rota, começa com/; quandonullapenas restringe os métodos HTTP da rota padrão sem registrar nova rotamethods: método(s) HTTP, string ou array de strings, ex.'GET'ou['GET','POST']name: nome da rota pararoute('name')geração de URL, pode ser omitido
Anotações sem parâmetros: restringir método HTTP na rota padrão
Sem caminho, restringe apenas os métodos HTTP permitidos para essa ação, continuando a usar o caminho padrão:
#[Post]
public function create() { ... } // Apenas POST permitido, o caminho continua /user/create
#[Get]
public function index() { ... } // Apenas GET permitido
Podem combinar-se várias anotações para permitir múltiplos métodos de requisição:
#[Get]
#[Post]
public function form() { ... } // Permite GET e POST
Métodos não declarados nas anotações retornarão 405.
Várias anotações com caminho registram rotas independentes: #[Get('/a')] #[Post('/b')] gera as rotas GET /a e POST /b.
Prefixo de grupo de rotas
Use #[RouteGroup] na classe para adicionar prefixo a todas as rotas dos métodos:
use support\annotation\route\RouteGroup;
use support\annotation\route\Get;
#[RouteGroup('/api/v1')]
class UserController
{
#[Get('/user/{id}')] // Caminho real /api/v1/user/{id}
public function show($id) { ... }
}
Métodos HTTP personalizados e nome da rota
#[Route] suporta vários métodos HTTP e o nome da rota:
use support\annotation\route\Route;
#[Route('/user', ['GET', 'POST'], 'user.form')]
public function form() { ... }
// Apenas caminho e método, sem nome da rota
#[Route('/user/update', 'PUT')]
public function update() { ... }
Parâmetros de caminho e regex
Rotas com anotações suportam a mesma sintaxe de parâmetros que config/route.php, incluindo regex e parâmetros opcionais:
#[Get('/user/{id:\d+}')] // Apenas id numérico
public function show($id) { ... }
#[Get('/user[/{name}]')] // name opcional: /user ou /user/xxx
public function list($name = null) { ... }
#[Any('/user/[{path:.+}]')] // Corresponde a /user e /user/ com qualquer sufixo
public function catchAll($path = null) { ... }
Consulte a seção «Parâmetros de rota» neste documento.
Middleware
#[Middleware] no controlador ou método afeta as rotas por anotações; uso igual a support\annotation\Middleware:
use support\annotation\Middleware;
#[Middleware(\app\middleware\AuthMiddleware::class)]
class UserController { ... }
#[Get('/user/{id}')]
#[Middleware(\app\middleware\RateLimitMiddleware::class)]
public function show($id) { ... }
Geração de URL com route()
Quando o nome da rota é especificado na anotação, use route('name', $params) para gerar a URL:
#[Get('/user/{id}', 'user.show')]
public function show($id) { ... }
// Uso: route('user.show', ['id' => 123]) => /user/123
Parâmetros de rota
Se houver parâmetros na rota, use {chave} para corresponder, e o resultado da correspondência será passado para os parâmetros do método do controlador (a partir do segundo parâmetro em diante), por exemplo:
// Correspondência com /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('Recebido o parâmetro'.$id);
}
}
Mais exemplos:
use support\Request;
// Correspondência com /user/123, não com /user/abc
Route::any('/user/{id:\d+}', function (Request $request, $id) {
return response($id);
});
// Correspondência com /user/foobar, não com /user/foo/bar
Route::any('/user/{name}', function (Request $request, $name) {
return response($name);
});
// Correspondência com /user /user/123 e /user/abc [] indica opcional
Route::any('/user[/{name}]', function (Request $request, $name = null) {
return response($name ?? 'tom');
});
// Corresponder a qualquer solicitação com prefixo /user/
Route::any('/user/[{path:.+}]', function (Request $request) {
return $request->path();
});
// Corresponder a todas as solicitações de opções : indica regex para o parâmetro nomeado
Route::options('[{path:.+}]', function () {
return response('');
});
Resumo de uso avançado
A sintaxe
[]nas rotas do Webman é usada principalmente para partes opcionais ou correspondências dinâmicas; permite definir estruturas de caminho mais complexas
:é usado para especificar expressão regular
Grupo de rotas
Às vezes, as rotas contêm um grande número de prefixos semelhantes, nesses casos, podemos usar grupos de rotas para simplificar a definição. Por exemplo:
Route::group('/blog', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
Equivalentemente
Route::any('/blog/create', function (Request $request) {return response('create');});
Route::any('/blog/edit', function (Request $request) {return response('edit');});
Route::any('/blog/view/{id}', function (Request $request, $id) {return response("view $id");});
Uso aninhado de grupos
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
});
Middleware de roteamento
Podemos definir um middleware para uma rota única ou para um grupo de rotas.
Por exemplo:
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('create');});
Route::any('/edit', function () {return response('edit');});
Route::any('/view/{id}', function ($request, $id) {return response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
# Exemplo errado (válido a partir do webman-framework >= 1.5.7)
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
# Exemplo correto
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
});
Roteamento de Recursos
Route::resource('/test', app\controller\IndexController::class);
// Rota de recurso específico
Route::resource('/test', app\controller\IndexController::class, ['index','create']);
// Rota de recurso não definida
// Se o endereço de acesso for notify, então qualquer tipo de rota /test/notify ou /test/notify/{id} é possível, com o nome da rota sendo test.notify
Route::resource('/test', app\controller\IndexController::class, ['index','create','notify']);
| Verb | URI | Ação | Nome da Rota |
|---|---|---|---|
| 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 |
Geração de URL
Observação
A geração de URL para rotas aninhadas em grupos não é suportada no momento
Por exemplo, para a rota:
Route::any('/blog/{id}', [app\controller\BlogController::class, 'view'])->name('blog.view');
Podemos usar o seguinte método para gerar a URL dessa rota.
route('blog.view', ['id' => 100]); // Resultado: /blog/100
Ao usar este método para URLs de rota em visualizações, a URL será gerada automaticamente, evitando a necessidade de alterar muitos arquivos de visualização devido a alterações nas regras de roteamento.
Obtendo informações de rota
Através do objeto $request->route, podemos obter informações sobre a rota atual, por exemplo:
$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());
}
Observação
Se a solicitação atual não corresponder a nenhuma rota configurada em config/route.php, então$request->routeserá nulo, ou seja, ao usar a rota padrão,$request->routeserá nulo.
Lidando com o erro 404
Quando a rota não é encontrada, o código de status 404 é retornado por padrão e o conteúdo 404 correspondente é exibido.
Se o desenvolvedor quiser intervir no fluxo de negócios quando a rota não é encontrada, pode usar o método de fallback de roteamento fornecido pelo webman. Por exemplo, a lógica a seguir redireciona para a página inicial quando a rota não é encontrada.
Route::fallback(function(){
return redirect('/');
});
Por exemplo, quando a rota não existe, retornar dados JSON é muito útil em webman quando é utilizado como uma interface de API.
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 not found']);
});
Adicionar middleware a 404
Por padrão, as solicitações 404 não passam por nenhum middleware. Se precisar adicionar middleware às solicitações 404, consulte o seguinte código:
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 not found']);
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
Link relacionado Página de erro personalizada
Desabilitar rota padrão
// Desabilitar a rota padrão do projeto principal, não afeta os plugins
Route::disableDefaultRoute();
// Desabilitar a rota admin do projeto principal, não afeta os plugins
Route::disableDefaultRoute('', 'admin');
// Desabilitar a rota padrão do plugin foo, não afeta o projeto principal
Route::disableDefaultRoute('foo');
// Desabilitar a rota admin do plugin foo, não afeta o projeto principal
Route::disableDefaultRoute('foo', 'admin');
// Desabilitar a rota padrão do controlador [\app\controller\IndexController::class, 'index']
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);
Anotação para desabilitar rota padrão
Podemos usar anotações para desabilitar a rota padrão de um controlador, por exemplo:
namespace app\controller;
use support\annotation\DisableDefaultRoute;
#[DisableDefaultRoute]
class IndexController
{
public function index()
{
return 'index';
}
}
Da mesma forma, também podemos usar anotações para desabilitar a rota padrão de um método do controlador, por exemplo:
namespace app\controller;
use support\annotation\DisableDefaultRoute;
class IndexController
{
#[DisableDefaultRoute]
public function index()
{
return 'index';
}
}
Interfaces de Roteamento
// Definir uma rota para qualquer método para $uri
Route::any($uri, $callback);
// Definir uma rota GET para $uri
Route::get($uri, $callback);
// Definir uma rota POST para $uri
Route::post($uri, $callback);
// Definir uma rota PUT para $uri
Route::put($uri, $callback);
// Definir uma rota PATCH para $uri
Route::patch($uri, $callback);
// Definir uma rota DELETE para $uri
Route::delete($uri, $callback);
// Definir uma rota HEAD para $uri
Route::head($uri, $callback);
// Definir uma rota OPTIONS para $uri
Route::options($uri, $callback);
// Definir várias rotas para tipos de solicitação múltiplos
Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
// Rota de grupo
Route::group($path, $callback);
// Rota de recurso
Route::resource($path, $callback, [$options]);
// Desativar rota padrão
Route::disableDefaultRoute($plugin = '');
// Rota de fallback, definir uma rota padrão padrão
Route::fallback($callback, $plugin = '');
// Obter todas as informações de rotas
Route::getRoutes();
Se não houver correspondência de rota para o $uri (incluindo a rota padrão), e fallback não estiver configurado, será retornado o código 404.
Vários arquivos de configuração de rota
Se você deseja gerenciar o roteamento usando vários arquivos de configuração de rota, por exemplo, em multiapp, onde cada aplicação tem seu próprio arquivo de configuração de rota, pode carregar o arquivo de configuração de rota externo usando require.
Por exemplo, em config/route.php:
<?php
// Carregar o arquivo de configuração de rota da aplicação admin
require_once app_path('admin/config/route.php');
// Carregar o arquivo de configuração de rota da aplicação api
require_once app_path('api/config/route.php');