API Reference — Blazor Blueprint
Login Register

Service Architecture

  • Web Service: Blazor Server UI with authentication (Port 8080)
  • Application Service: REST API with JWT authentication (Port 8081)
  • MongoDB: Document database (Port 27017)
  • Redis: Cache and messaging (Port 6379)

The Application Service is a separate ASP.NET Core WebAPI process that handles data-oriented requests. The web application communicates with it via HTTP using JWT authentication, automatically forwarding the current organisation context.

API Documentation

Scoped Controller Pattern

API controllers are categorised into two scopes using attributes and base classes:

Organisation-Scoped

Inherit from OrganisationApiController and are marked with [OrganisationScoped]. These require an X-Organisation-Id header. The ApiTenantResolutionMiddleware resolves the organisation, sets the tenant context, and all IRepository<T> queries are automatically scoped to that org's database.

public class MyController : OrganisationApiController
{
// CurrentOrganisationName, CurrentOrganisationId available
// IRepository<T> queries scoped to org's database
}

Platform-Scoped

Inherit from PlatformApiController and are marked with [PlatformScoped]. No organisation context is needed. Used for authentication endpoints and platform-level operations.

[AllowAnonymous]
public class TokenController : PlatformApiController
{
// No tenant resolution, uses IPlatformRepository<T>
}

Authentication

Service-to-Service (Web → API)

The web application authenticates using client credentials. The JwtAuthenticationHandler handles this automatically on every request: it requests a token from IJwtTokenApiClient.GetServiceTokenAsync — which caches one token per organisation — and stamps the matching X-Organisation-Id header.

Each issued JWT is bound to a specific organisation via an org_id claim. The API rejects any request where the bearer token's org_id does not match the X-Organisation-Id header — a leaked token can only act on the organisation it was minted for. Tokens minted without an OrganisationId are usable only against [PlatformScoped] endpoints.

POST /api/token
{
  "ClientId": "blazorblueprint-web",
  "ClientSecret": "...",
  "OrganisationId": "<org-guid>"  // optional; required for [OrganisationScoped] calls
}

# Subsequent requests:
Authorization: Bearer <jwt-with-org_id-claim>
X-Organisation-Id: <same-org-guid>

Configuration: Client credentials are stored in appsettings.json under Services:ApplicationService. Both base controllers use [Authorize(Policy = "ServiceClient")], so any future co-tenant of the JWT secret can't reach the API without the ServiceClient role.

Current Endpoints

Method Route Scope Description
POST /api/token Platform Client credentials token exchange
GET /api/organisations/current Organisation Trimmed view of the organisation the JWT is bound to
GET /api/weatherforecast Organisation Weather demo (Redis cached, returns org name)
GET /api/weatherforecast/page-cache Organisation Weather demo (no server cache, returns org name)

See the Caching Demos to see the tenant context in action — the API response includes the resolved organisation name.

Ready to Download?

Start building with Blazor Blueprint's service architecture and APIs. Download the full product free — use it, including commercially, while you're under £100k/year revenue; a commercial licence (from £499) applies above that.

🔓 Source-available on GitHub • Free under £100k/yr revenue • Commercial licence (from £499) above that • Full source code included

Welcome! How can we help you today?
An unhandled error has occurred. Reload