Files
AgenticCode/ARCHITECTURE.md
local 711df97ce9 feat(01-03): implement echo chat UI with MudBlazor
Add ChatGPT-style chat interface using MudBlazor components. User messages
display on the right (purple), bot echoes "success msg!" on the left.
Includes app bar, centered 768px layout, bottom-anchored messages, and
documented inline comments on every Blazor concept introduced.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 01:51:53 +01:00

4.6 KiB

Architecture Decisions

Blazor Hosting Model: Server vs WebAssembly

How They Differ

Aspect Blazor Server Blazor WASM
Code runs On the server In the browser
UI updates Via SignalR WebSocket (server pushes diffs) Locally in browser (no round-trip)
Calling backend services Direct — code is already server-side Needs HTTP calls if accessing server resources
Offline capable No (requires persistent connection) Yes
Startup speed Fast Slower (downloads .NET runtime to browser)

Decision: Blazor WASM

This project uses Blazor WebAssembly (standalone) with a separate ASP.NET Core Web API backend.

When Do You Need a Separate API Project?

There are two distinct concerns that are easy to conflate:

1. Consuming an External API (e.g. OpenAI)

Both Blazor Server and WASM can call external APIs directly from C# — no controller needed. The difference is where that code executes:

  • Blazor Server: Code runs on the server. A service class calls OpenAI directly. API keys live safely in server memory. No controller, no exposed endpoint required.
  • Blazor WASM: Code runs in the browser. You can call OpenAI directly, but any API key would be embedded in the browser download — anyone could inspect it via browser dev tools. This is the primary reason to add a backend proxy.

2. Exposing an API Endpoint (e.g. ChatAgent.Api)

This is a separate concern. You expose an API endpoint when:

  • Another application needs to communicate with your chat system
  • You want a REST API for mobile clients, scripts, or integrations
  • You need a server-side proxy to protect secrets from the browser (the WASM case above)

Key insight: You don't need an API endpoint to use an external service. You only need one in WASM to keep secrets out of the browser.

3. Component Updates Do Not Require an API

In both hosting models, Blazor components update themselves locally:

  • Components hold state in fields/properties
  • Calling StateHasChanged() triggers a re-render
  • Components can call injected C# services directly
  • No HTTP round-trip is needed for UI updates

For example, a chat component that echoes "success msg!" back needs no API at all — a simple injected service handles it entirely within the client project.

API Key Management Scenarios

The need for an API project in WASM depends on how secrets are managed:

Scenario WASM needs API project? Why
Raw API key in config Yes To keep the key out of browser-downloadable code
Azure Key Vault Yes Browser sandbox cannot access Key Vault or managed identity
API Management gateway (Azure APIM) with token auth No WASM calls the gateway directly; gateway handles auth via managed identity
Blazor Server (any scenario) No Code is already server-side; secrets never leave the server

Enterprise Pattern: API Gateway

In enterprise environments, a common pattern avoids the need for a custom API proxy entirely:

  1. An API Management gateway (e.g. Azure APIM) sits in front of the external service (e.g. OpenAI)
  2. The gateway authenticates via managed identity and handles secret retrieval
  3. The gateway exposes a public endpoint requiring only a subscription key or OAuth token
  4. WASM calls the gateway directly — no secrets in the browser, no custom API project needed

The "proxy" becomes infrastructure rather than application code.

Current Project Structure

ChatAgent.sln
src/
  ChatAgent.Client/    -- Blazor WASM (standalone)
    Pages/             -- Routable page components
    Layout/            -- MainLayout, NavMenu
    Services/          -- Client-side services (e.g. ChatApiClient)
    Program.cs         -- Client entry point, DI registration
  ChatAgent.Api/       -- ASP.NET Core Web API (backend proxy)
    Controllers/       -- API controllers (e.g. HealthController)
    Program.cs         -- Server entry point, middleware config
  ChatAgent.Shared/    -- Models shared between Client and Api
    Models/            -- DTOs (e.g. HealthResponse)

Why Three Projects?

  • ChatAgent.Client: The Blazor WASM app running in the browser
  • ChatAgent.Api: Exists to proxy requests that require server-side secrets (e.g. future OpenAI calls). Not needed for basic component interactions.
  • ChatAgent.Shared: Models referenced by both Client and Api, avoiding duplication

For the initial "echo success" phase, only ChatAgent.Client is actively used. The Api and Shared projects exist to support future integration with external services that require secret management.