Roteamento
As rotas permitem que o mundo externo interaja com seu aplicativo por meio de URLs.
As rotas são registradas dentro do arquivo start/routes.js
.
Roteamento básico
A vinculação de rota mais básica requer uma URL e um fechamento:
// .start/routes.js
Route.get('/', () => 'Hello Adonis')
O valor de retorno do fechamento será enviado de volta ao cliente como uma resposta.
Você também pode vincular uma rota a um controlador usando uma assinatura controller.method
:
// .start/routes.js
Route.get('posts', 'PostController.index')
A assinatura PostController.index
acima se refere ao método index
do arquivo App/Controllers/Http/PostController.js
.
Métodos de roteador disponíveis
Rotas com recursos usam diferentes verbos HTTP para indicar o tipo de solicitação:
Route.get(url, closure)
Route.post(url, closure)
Route.put(url, closure)
Route.patch(url, closure)
Route.delete(url, closure)
Para registrar uma rota que responde a vários verbos, use Route.route
:
Route.route('/', () => {
//
}, ['GET', 'POST', 'PUT'])
Para renderizar uma visualização diretamente (por exemplo, páginas estáticas), use Route.on.render
:
Route.on('/').render('welcome')
No exemplo acima, quando a rota raiz /
é carregada, o arquivo resources/view/welcome.edge
é renderizado diretamente.
Parâmetros de rota
Parâmetros obrigatórios
Para rotas dinâmicas, você pode definir parâmetros de rota como:
// .start/routes.js
Route.get('posts/:id', ({ params }) => {
return `Post ${params.id}`
})
No exemplo acima, :id
é um parâmetro de rota.
Seu valor é então recuperado por meio do objeto params
.
Parâmetros opcionais
Para definir um parâmetro de rota opcional, anexe um símbolo ?
à sua definição:
// .start/routes.js
Route.get('make/:drink?', ({ params }) => {
// use Coffee como alternativa quando a bebida não estiver definida
const drink = params.drink || 'Coffee'
return `One ${drink}, coming right up!`
})
No exemplo acima, :drink?
é um parâmetro de rota opcional.
Rota curinga
Você pode querer renderizar uma única visualização do servidor e manipular o roteamento usando sua estrutura de front-end preferida:
// .start/routes.js
Route.any('*', ({ view }) => view.render('...'))
Todas as rotas específicas precisam ser definidas antes da sua rota curinga:
// .start/routes.js
Route.get('api/v1/users', closure)
Route.any('*', ({ view }) => view.render('...'))
Rota nomeada
Embora as rotas sejam definidas dentro do arquivo start/routes.js
, elas são referenciadas em todos os outros lugares do aplicativo (por exemplo, usando o auxiliar de rota views
para criar uma URL para uma determinada rota).
Usando o método as()
, você pode atribuir um nome exclusivo à sua rota:
// .start/routes.js
Route.get('users', closure).as('users.index')
Isso permitirá que você use auxiliares route
em seus modelos e código, como este:
<!-- before -->
<a href="/users">List of users</a>
<!-- after -->
<a href="{{ route('users.index') }}">List of users</a>
foo ({ response }) {
return response.route('users.index')
}
Ambos os auxiliares route
compartilham a mesma assinatura e aceitam um objeto de parâmetros opcional como seu segundo argumento:
Route.get('posts/:id', closure).as('posts.show')
route('posts.show', { id: 1 })
Os auxiliares route
também aceitam um objeto de parâmetros opcional como um terceiro argumento para manipular as opções protocol
, domain
e query
:
route('posts.show', { id: 1 }, {
query: { foo: 'bar' }
});
// resultando em /post/1?foo=bar
// Sem parâmetros:
route('auth.login', null, {
domain: 'auth.example.com',
protocol: 'https',
query: { redirect: '/dashboard' }
});
// resultando em https://auth.example.com/login?redirect=%2Fdashboard
As mesmas regras se aplicam à visualização.
<a href="{{ route('posts.show', { id: 1 }, {query: { foo: 'bar' }}) }}">Show post</a>
// href="/post/1?foo=bar"
Formatos de rota
Os formatos de rota abrem uma nova maneira para negociação de conteúdo, onde você pode aceitar o formato de resposta como parte da URL.
Um formato de rota é um contrato entre o cliente e o servidor para qual tipo de resposta retornar:
// .start/routes.js
Route.get('users', async ({ request, view }) => {
const users = await User.all()
if (request.format() === 'json') {
return users
}
return view.render('users.index', { users })
}).formats(['json'])
Para o exemplo acima, o endpoint /users
poderá responder em vários formatos com base na URL:
GET /users.json # Retorna uma matriz de usuários em JSON
GET /users # Retorna a visualização em HTML
Você também pode desabilitar a URL padrão e forçar o cliente a definir o formato:
// .start/routes.js
Route.get('users', closure).formats(['json', 'html'], true)
Passar true
como o segundo argumento garante que o cliente especifique um dos formatos esperados. Caso contrário, um erro 404 será lançado.
Recursos de rota
Você frequentemente criará rotas engenhosas para fazer operações CRUD em um recurso.
Route.resource
atribui rotas CRUD a um controlador usando uma única linha de código:
// .start/routes.js
// Isso...
Route.resource('users', 'UserController')
// ...equivale a isso:
Route.get('users', 'UserController.index').as('users.index')
Route.post('users', 'UserController.store').as('users.store')
Route.get('users/create', 'UserController.create').as('users.create')
Route.get('users/:id', 'UserController.show').as('users.show')
Route.put('users/:id', 'UserController.update').as('users.update')
Route.patch('users/:id', 'UserController.update')
Route.get('users/:id/edit', 'UserController.edit').as('users.edit')
Route.delete('users/:id', 'UserController.destroy').as('users.destroy')
OBSERVAÇÃO
Este recurso só está disponível ao vincular rotas a um Controlador.
Você também pode definir recursos aninhados:
// .start/routes.js
Route.resource('posts.comments', 'PostCommentController')
Filtrando recursos
Você pode limitar as rotas atribuídas pelo método Route.resource
encadeando um dos métodos de filtro abaixo.
apiOnly
Remove as rotas GET resource/create
e GET resource/:id/edit
:
// .start/routes.js
Route.resource('users', 'UserController')
.apiOnly()
only
Mantém apenas as rotas passadas:
// .start/routes.js
Route.resource('users', 'UserController')
.only(['index', 'show'])
except
Mantém todas as rotas, exceto as rotas passadas:
// .start/routes.js
Route.resource('users', 'UserController')
.except(['index', 'show'])
Middleware de recurso
Você pode anexar middleware a qualquer recurso como faria com uma única rota:
// .start/routes.js
Route.resource('users', 'UserController')
.middleware(['auth'])
Se não quiser anexar middleware a todas as rotas geradas via Route.resource
, você pode personalizar esse comportamento passando um Map
para o método middleware
:
// .start/routes.js
Route.resource('users', 'UserController')
.middleware(new Map([
[['store', 'update', 'destroy'], ['auth']]
]))
No exemplo acima, o middleware auth é apenas aplicado às rotas store, update e destroy.
Formatos de recursos
Você pode definir formatos de resposta para rotas com recursos por meio do método formats
:
// .start/routes.js
Route.resource('users', 'UserController')
.formats(['json'])
Domínios de roteamento
Seu aplicativo pode usar vários domínios.
O AdonisJs torna super fácil lidar com esse caso de uso.
Os domínios podem ser um ponto de extremidade estático como blog.adonisjs.com
ou um ponto de extremidade dinâmico como :user.adonisjs.com
.
OBSERVAÇÃO
Você também pode definir o domínio em uma única rota.
// .start/routes.js
Route.group(() => {
Route.get('/', ({ subdomains }) => {
return `The username is ${subdomains.user}`
})
}).domain(':user.myapp.com')
No exemplo acima, se você visitou virk.myapp.com
, verá The username is virk
.
Grupos de Rota
Se as rotas do seu aplicativo compartilham lógica/configuração comum, em vez de redefinir a configuração para cada rota, você pode agrupá-las assim:
// .start/routes.js
// Desagrupado
Route.get('api/v1/users', closure)
Route.post('api/v1/users', closure)
// Agrupado
Route.group(() => {
Route.get('users', closure)
Route.post('users', closure)
}).prefix('api/v1')
Prefixo
Prefixe todas as URLs de rota definidas no grupo:
// .start/routes.js
Route.group(() => {
Route.get('users', closure) // GET /api/v1/users
Route.post('users', closure) // POST /api/v1/users
}).prefix('api/v1')
Middleware
Atribua um ou muitos middlewares ao grupo de rotas:
// .start/routes.js
Route.group(() => {
//
}).middleware(['auth'])
OBSERVAÇÃO
O middleware do grupo é executado antes do middleware da rota.
Namespace
Prefixe o namespace do controlador vinculado:
// .start/routes.js
Route.group(() => {
// Vincula '/users' a 'App/Controllers/Http/Admin/UserController'
Route.resource('/users', 'UserController')
}).namespace('Admin')
Formatos
Define formatos para todas as rotas no grupo:
// .start/routes.js
Route.group(() => {
//
}).formats(['json', 'html'], true)
Domínio
Especifique a qual grupo de domínio as rotas pertencem:
// .start/routes.js
Route.group(() => {
//
}).domain('blog.adonisjs.com')