perf(api): cache BookController JsonSerializerOptions instead of per-request allocation (CA1869) #661

Closed
opened 2026-07-17 16:17:43 +00:00 by spikerj · 1 comment
Owner

BookController created a fresh new JsonSerializerOptions { PropertyNamingPolicy = CamelCase } at 7 call sites — each request/publish path builds a throwaway options instance. System.Text.Json caches type metadata per options-instance, so a new instance every call repeatedly rebuilds that reflection cache (CA1869), adding avoidable allocation and CPU on the book-upload/quiz/embedding publish paths.

Fix: hoist a single private static readonly JsonSerializerOptions CamelCaseJson and point all 7 sites at it. The options object is immutable after first use and safe for concurrent reads, so a shared static is correct. All 7 sites used the identical camelCase-only config, so behavior is unchanged.

Scope: SpikerSoft.Api/Domain/Books/BookController.cs only. Verified dotnet build SpikerSoft.API.csproj clean (0 errors). SonarQube rule external_roslyn:CA1869.

BookController created a fresh `new JsonSerializerOptions { PropertyNamingPolicy = CamelCase }` at 7 call sites — each request/publish path builds a throwaway options instance. System.Text.Json caches type metadata **per options-instance**, so a new instance every call repeatedly rebuilds that reflection cache (CA1869), adding avoidable allocation and CPU on the book-upload/quiz/embedding publish paths. **Fix:** hoist a single `private static readonly JsonSerializerOptions CamelCaseJson` and point all 7 sites at it. The options object is immutable after first use and safe for concurrent reads, so a shared static is correct. All 7 sites used the identical camelCase-only config, so behavior is unchanged. Scope: `SpikerSoft.Api/Domain/Books/BookController.cs` only. Verified `dotnet build SpikerSoft.API.csproj` clean (0 errors). SonarQube rule external_roslyn:CA1869.
Author
Owner

Resolved in spikersoft-backend PR #364 (merged to master). Hoisted a single static readonly CamelCaseJson and pointed all 7 BookController serialization sites at it; identical config so no behavior change (CA1869). Substantive CI (unit tests, amd64+arm64 build, manifest) all green; merged past the non-blocking notify job. Closing.

Resolved in spikersoft-backend PR #364 (merged to `master`). Hoisted a single static readonly CamelCaseJson and pointed all 7 BookController serialization sites at it; identical config so no behavior change (CA1869). Substantive CI (unit tests, amd64+arm64 build, manifest) all green; merged past the non-blocking notify job. Closing.
Sign in to join this conversation.