Arquitetura da Aplicação#
Visão Geral#
A aplicação UNICEF Portugal é uma aplicação híbrida ASP.NET MVC + AngularJS SPA, construída sobre o Umbraco 7.15.4. O AngularJS não é um processo ou servidor separado -- é HTML/JS estático servido a partir do mesmo Azure App Service.
O conceito de "SPA" (Single Page Application) significa que o browser descarrega uma única página HTML (index.html) e, a partir daí, carrega dinamicamente todo o conteúdo através de chamadas API ao backend Umbraco. Isto implica que se a API do Umbraco estiver lenta, todas as páginas ficam bloqueadas.
O backoffice do Umbraco (/umbraco) é separado e utiliza o Angular próprio do Umbraco (backoffice Angular), que não tem relação com o AngularJS do frontend.
Diagrama de Arquitetura#
graph TB
subgraph Browser
A["index.html - ng-app=unicef"] --> B["AngularJS + ui-router - HTML5 mode"]
B --> C["Catch-all route - *myPath"]
end
subgraph "Azure App Service"
D["ContentApiController.cs - /umbraco/Api/ContentApi/GetData/"]
E["Umbraco 7.15.4 - Cache de Conteudo"]
F["/Assets/ngviews/ - Templates estaticos .html"]
G["Umbraco Backoffice - /umbraco"]
end
subgraph "Base de Dados"
H[(SQL Server)]
end
C -->|GET /umbraco/Api/ContentApi/GetData/?url=path| D
D --> E
E --> H
D -->|JSON: data + meta.template| B
B -->|ng-include template| F
G --> E
Fluxo de Carregamento de Página#
sequenceDiagram
participant U as Utilizador
participant B as Browser
participant NG as AngularJS
participant API as ContentApiController
participant UMB as Umbraco Cache
participant DB as SQL Server
U->>B: Navega para /pagina-exemplo
B->>NG: Carrega index.html (ng-app="unicef")
NG->>NG: ui-router intercepta via catch-all (*myPath)
NG->>API: GET /umbraco/Api/ContentApi/GetData/?url=/pagina-exemplo
API->>UMB: Procura conteudo na cache
UMB->>DB: Query (se nao estiver em cache)
DB-->>UMB: Dados
UMB-->>API: Conteudo encontrado
API-->>NG: JSON {data: {title, body, image...}, meta: {template: "/Assets/ngviews/..."}}
NG->>NG: Processa resposta (crops, share links)
NG->>B: ng-include carrega template de /Assets/ngviews/
B-->>U: Pagina renderizada
Implicação de Performance
Se o ContentApiController estiver lento (por exemplo, devido ao excesso de dados na base de dados), o spinner de carregamento fica visível indefinidamente, pois o AngularJS aguarda a resposta da API para renderizar qualquer conteúdo.
Estrutura da Solução#
A solução Visual Studio é composta pelos seguintes projetos:
| Projeto | Descrição |
|---|---|
| Web (Web.csproj) | Projeto web principal. Host do Umbraco, API controllers, views |
| Business (Business.csproj) | ViewModels e lógica de negócio |
| Definitions (Definitions.csproj) | Modelos e interfaces |
| DB (DB.sqlproj) | Projeto de base de dados SQL Server |
| PaymentsManager (PaymentsManager.csproj) | Processamento de pagamentos EasyPay/PayPal |
| DAL.Payments (DAL.Payments.csproj) | Acesso a dados para pagamentos |
| MassiveLuceneAnalyser | Analisador Lucene customizado para pesquisa |
| Templates/app/ | Código fonte do frontend AngularJS (index.html, Assets/js/, Assets/ngviews/) |
Como Funciona#
- O browser carrega
index.htmlque contém<html ng-app="unicef"> - O AngularJS faz bootstrap e ativa o
ui-routercom HTML5 mode - Uma rota catch-all (
*myPath) intercepta toda a navegação - Para cada página, o Angular chama
/umbraco/Api/ContentApi/GetData/?url=<path> - O
ContentApiController.cs(server-side) procura o conteúdo na cache do Umbraco - Retorna JSON com os dados e o caminho do template:
{data: {...}, meta: {template: "/Assets/ngviews/..."}} - O Angular renderiza o template via
ng-includecom os dados recebidos - Os templates são ficheiros
.htmlestáticos em/Assets/ngviews/