Angular: Rotas para aplicações Multi Tenant
Esses dias fui designado para a missão de reestruturar uma aplicação Angular para multi-tenant. Teria sido mais complexo há alguns meses, mas graças à versão 5.2 do framework, essa realidade mudou.
Entendendo a situação
Imagine que uma rede hoteleira possui vários hotéis e um usuário da rede geralmente tem acesso a mais de um hotel. Esse usuário pode ser um gerente responsável por várias unidades que precisa alternar entre elas rapidamente, e até mesmo adicionar aos favoritos para acessar posteriormente.
Tá, mas eu preciso gerenciar isso no front-end?
Sim e não. Depende muito do seu objetivo.
Seria muito mais simples guardar o hotel selecionado no localStorage
e usar um botão para alternar entre eles. Porém, sabendo que o usuário precisa trabalhar em vários hotéis simultaneamente, fica a pergunta: Como permitir a rápida alternância entre hotéis e tornar isso transparente para o usuário? Como guardar a informação do hotel na URL e tornar possível o bookmark?
Route Parameters
O Angular possui o recurso de Route Parameters, que traduz a informação na URL em parâmetros acessíveis via ActivatedRoute
.
// src/app/app-routing.module.tsexport const routes: Routes = [
{
path: 'admin/:hotel',
component: AdminTemplateComponent,
children: [
{ path: '', component: HotelConfigComponent }
]
}
];@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})export class AppRoutingModule {}
Note que se eu acessar /admin/1/config
, o parâmetro hotel com o valor 1 estará disponível apenas no componente AdminTemplateComponent
. Porém, nesse caso, nenhum elemento filho consegue acessar os valores da rota do componente pai. Sendo assim, eu não conseguirei acessar o parâmetro hotel dentro de HotelConfigComponent
, e não terei os dados do hotel para enviar nas minhas requisições.
Herança de parâmetros
Anteriormente, um componente só conseguia acessar os parâmetros de uma rota pai com algumas regras especiais (quando a rota tinha um caminho vazio, ou se não tivesse componente). Como na maioria dos casos é necessário um componente de template e/ou um container, essa opção não era muito atrativa.
Porém, na versão 5.2, o Angular trouxe o recurso de herança de parâmetros chamado paramsInheritanceStrategy
, que quando setada para always
, faz com que todas as rotas filhas herdem os parâmetros das rotas pai.
// src/app/app-routing.module.tsexport const routes: Routes = [
{
path: 'admin/:hotel',
component: AdminTemplateComponent,
children: [
{ path: '', component: HotelConfigComponent }
]
}
];@NgModule({
imports: [RouterModule.forRoot(routes, {
paramsInheritanceStrategy: 'always'
})],
exports: [RouterModule]
})export class AppRoutingModule {}
Editando o nosso arquivo de rotas e adicionando a configuração de herança, eu consigo acessar o parâmetro hotel em qualquer componente da aplicação. E caso o usuário tenha duas ou mais abas abertas, cada uma com um hotel diferente, eu posso diferenciá-las tranquilamente pelo parâmetro recebido via URL, oferecendo uma experiência melhor.