Skip to main content

Velox Web2 Architecture

This document is based on source inspection of the velox-web2 repository. Where behavior is not clear from source, it is marked as unclear.

Overall Architecture

velox-web2 is a newer .NET 9 solution that appears to front the Delphi VeloxAPIService and provide API documentation/proxy behavior. It also contains a default Blazor web project scaffold.

The solution has four projects:

  • Velox.AppHost: .NET Aspire distributed application host.
  • Velox.ServiceDefaults: shared Aspire/service defaults for telemetry, service discovery, resilience, and health checks.
  • Velox.ApiService: ASP.NET Core API documentation/proxy service.
  • Velox.Web: Blazor Server-style web frontend scaffold.

The most product-specific project is Velox.ApiService. It reads the Velox config database to discover active APIs/actions, serves OpenAPI files from wwwroot\openapi, exposes Scalar/Swagger UI, and maps proxy endpoints that forward calls to the Delphi VeloxAPIService.

Solution and Project Structure

Main solution: Velox.sln.

Project structure:

  • Velox.AppHost\AppHost.cs: Aspire composition entry point.
  • Velox.ServiceDefaults\Extensions.cs: shared service defaults.
  • Velox.ApiService\Program.cs: API proxy/documentation startup.
  • Velox.ApiService\DBContext: EF Core contexts for VxConfig and VxData.
  • Velox.ApiService\ModelConfig: generated/config EF models for Velox config tables.
  • Velox.ApiService\ModelData: generated/data EF models for VxData tables.
  • Velox.ApiService\Endpoints: proxy endpoint implementation.
  • Velox.ApiService\Service: user/auth and logging helpers.
  • Velox.ApiService\wwwroot: static landing pages, OpenAPI files, Scalar/Swagger customization, and images.
  • Velox.Web\Components: Blazor app/components/pages.

Startup Sequence for Each Executable

Velox.AppHost

Entry point: Velox.AppHost\AppHost.cs.

Startup sequence:

  1. Create a distributed application builder.
  2. Add Velox.ApiService as project name api and attach /health check.
  3. Add Velox.Web as project name web.
  4. Give the web project external HTTP endpoints.
  5. Attach /health check.
  6. Reference and wait for the API project.
  7. Build and run the distributed application.

Velox.ApiService

Entry point: Velox.ApiService\Program.cs.

Startup sequence:

  1. Create a web application builder.
  2. Add service defaults from Velox.ServiceDefaults.
  3. Configure custom logging through AddLogging().
  4. Add Problem Details support.
  5. Register VxConfigContext using ConnectionStrings:VxConfig.
  6. Register VxDataContext using ConnectionStrings:VxData.
  7. Enable EF sensitive data logging and detailed errors on both contexts.
  8. Register named HttpClient named proxy.
  9. Register IUserService.
  10. Build the app.
  11. Enable default/static file serving.
  12. Create a scope and query VX_SETUP, active VX_API, and active API actions from VxConfigContext.
  13. Map one /openapi/<schemaName> endpoint for each active API schema.
  14. Configure development no-cache headers or production Problem Details exception handling.
  15. Map generated OpenAPI, Scalar API reference, and Swagger UI.
  16. Enable HTTPS redirection and status-code Problem Details.
  17. For each active API action, map a route based on API base URL and action endpoint/method.
  18. Proxy each mapped route to the configured Delphi VeloxAPIService address.
  19. Map default health endpoints.
  20. Run the app.

Velox.Web

Entry point: Velox.Web\Program.cs.

Startup sequence:

  1. Create a web application builder.
  2. Add service defaults.
  3. Add Razor components with interactive server components.
  4. Add output cache.
  5. Register typed WeatherApiClient with service discovery base address https+http://apiservice.
  6. Build the app.
  7. Configure production exception handler/HSTS.
  8. Enable HTTPS redirection, antiforgery, and output cache.
  9. Map static assets.
  10. Map Razor components with interactive server render mode.
  11. Map default health endpoints.
  12. Run the app.

Velox.Web still contains default pages such as weather/counter/home. Its product role is unclear beyond being the future web frontend scaffold.

Purpose of Each Major Project

  • Velox.AppHost: local/distributed orchestration for API and web projects.
  • Velox.ServiceDefaults: shared defaults for OpenTelemetry, service discovery, HTTP resilience, and health checks.
  • Velox.ApiService: API documentation UI and proxy to Delphi VeloxAPIService.
  • Velox.Web: Blazor frontend scaffold.

Key Frameworks and Libraries

Visible frameworks/packages:

  • .NET 9.
  • ASP.NET Core.
  • .NET Aspire AppHost.
  • Blazor/Razor Components.
  • Entity Framework Core SQL Server.
  • Scalar.AspNetCore.
  • Swashbuckle.AspNetCore.
  • Microsoft.AspNetCore.OpenApi.
  • OpenTelemetry metrics/tracing/logging.
  • Microsoft service discovery and HTTP resilience.

Configuration Loading

Configuration is loaded through standard ASP.NET Core configuration:

  • Velox.ApiService\appsettings.json and environment-specific overrides.
  • Velox.Web\appsettings.json.
  • Velox.AppHost\appsettings.json.
  • User secrets are configured for AppHost through its project file.

Velox.ApiService uses connection strings named:

  • VxConfig.
  • VxData.

It then loads runtime API route configuration from Velox config database tables:

  • VX_SETUP through VxSetup to get the API address.
  • VX_API through VxApi to discover active API definitions and OpenAPI schema names.
  • VX_API_ACTION and VX_ACTION through VxApiAction/VxAction to discover active API action routes and HTTP methods.

Sensitive-looking database connection strings are present in local appsettings files and are not reproduced here.

Logging

Velox.ApiService\Service\LoggingExtension.cs clears default logging providers and adds:

  • Single-line console logging with UTC timestamps.
  • Debug logging.
  • Windows Event Log logging with source VeloxAPI when running on Windows.

Velox.ServiceDefaults adds OpenTelemetry logging/metrics/tracing. OTLP export is enabled when OTEL_EXPORTER_OTLP_ENDPOINT is configured.

The API service also writes route mappings to ILogger<Program> and Console.WriteLine at startup.

Database Access Architecture

Velox.ApiService uses EF Core contexts:

  • VxConfigContext maps Velox config tables such as VX_ACTION, VX_API, VX_API_ACTION, VX_SETUP, VX_LOG, VX_TRANSPORT, and module-related tables.
  • VxDataContext maps VxData tables such as application, party, order, shipment, invoice, user, web hook, and many other domain tables.

These contexts appear generated/scaffolded from the databases. They use SQL Server and include extensive OnModelCreating mappings.

The API route-discovery query is startup-only. If API definitions change in the config database after the service starts, the routes appear not to refresh until restart. No runtime resynchronization was found.

Plugin/Module Architecture

There is no general plugin architecture.

The main dynamic/module-like behavior is database-driven route mapping:

  • Active VX_API rows define API documents/base URLs.
  • Active VX_API_ACTION plus VX_ACTION rows define endpoint paths and HTTP methods.
  • The API service maps routes at startup based on those records.

Aspire project composition is static in AppHost.cs.

Flow Execution Architecture

Velox.ApiService does not execute Velox flows itself.

Flow/API requests are proxied:

  1. Incoming request hits a dynamically mapped route.
  2. ProxyEndpoint.ProxyVeloxAPIService authenticates the bearer token through IUserService.
  3. IUserService treats a bearer token as a GUID user id and looks it up in the VxData User table.
  4. The proxy builds an upstream request to the Delphi VeloxAPIService endpoint from VX_SETUP.Apiaddress plus the action endpoint.
  5. The proxy forwards selected request headers and request body for POST/PUT/PATCH.
  6. The proxy adds X-UserNum and Forwarded headers.
  7. The upstream response stream is copied back to the client.

The Delphi VeloxAPIService remains the flow execution host.

Serialization Formats

Visible formats include:

  • JSON appsettings.
  • OpenAPI JSON documents under wwwroot\openapi.
  • Swagger/Scalar static JS/CSS config.
  • EF Core C# model/context classes.
  • Razor components.
  • Static HTML, CSS, JS, SVG, and PNG assets.
  • Docker Compose notes/text files.

Major Design Patterns Used

  • Aspire AppHost composition.
  • Shared service-default extension methods.
  • Minimal API route mapping.
  • Database-driven endpoint discovery.
  • Reverse proxy/adapter endpoint.
  • EF Core database-first/scaffolded contexts.
  • Problem Details for errors.
  • OpenTelemetry instrumentation defaults.

Areas of Technical Debt

  • EF sensitive data logging is enabled for both contexts.
  • Authentication currently treats bearer tokens as raw user GUIDs; token issuance/expiry/claims are unclear.
  • The proxy replaces https with http in the upstream base URL as a local testing fix.
  • Startup uses First() for setup loading; behavior with no setup row is unclear and likely fails startup.
  • Dynamic API route mapping happens at startup only.
  • Generated EF contexts are very large, which can make manual review and merge work difficult.
  • Velox.Web still contains scaffold/sample pages, so its final product architecture is unclear.
  • Local appsettings include machine-specific connection strings.

Questions About the Architecture

  • Is Velox.ApiService intended to replace the older velox-web API surface or only front the Delphi API service?
  • What is the intended production authentication model for API clients?
  • Should route/API configuration refresh without restarting the service?
  • Where are OpenAPI files under wwwroot\openapi generated from, and what process keeps them in sync with VX_API records?
  • What is the final role of Velox.Web in this solution?