---
title: SAIF.Web.API.Core architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: andmil
last_reviewed: 2026-09-15
library: SAIF.Web.API.Core
reference_type: package
---

# SAIF.Web.API.Core architecture

SAIF.Web.API.Core is a shared contracts/cross-cutting class library that defines API response envelopes (`SAIF.API.Responses`), a typed exception hierarchy (`SAIF.API.Exceptions`), and an unrelated build/version-metadata utility (`BuildInfo`); it contains no business logic, no services, no controllers, and performs no network or database I/O, and it has no independent package identity of its own — it is compiled as a separate assembly but bundled into the `SAIF.Web.API.Clients` NuGet package via `IncludeReferencedProjects=true`.

## Responsibilities
- Define response envelope data-transfer objects (`ApiResponse<T>`, `ErrorResponse`) used to represent API results and serializable error payloads.
- Define a typed exception hierarchy rooted at the abstract `SAIFException` (`NoMatchingDataException`, `UnauthorizedAccessException`, `InternalServerError`, `InvalidDataException`) so HTTP failure semantics can be expressed as strongly-typed .NET exceptions rather than raw status codes ([BR-CORE-002](business-rules.md#br-core-002-httpstatuscode-carried-by-every-saifexception-subtype), [BR-CORE-003](business-rules.md#br-core-003-fixed-default-exception-messages)).
- Carry an `HttpStatusCode` on every `SAIFException`-derived instance so HTTP-facing consumers can associate/read a status after construction ([BR-CORE-002](business-rules.md#br-core-002-httpstatuscode-carried-by-every-saifexception-subtype)) — the decision of *which* status maps to *which* exception type is made entirely by the consumer, not by this library.
- Provide `BuildInfo.GetBuildInfo`, a standalone static utility that reads an optional `version*.dat`-pattern file from a caller-supplied directory and returns build/version metadata as key/value pairs, tolerating the file's absence.

## Component boundaries
- `SAIF.API.Responses` namespace (`ApiResponse.cs`, `ErrorResponse.cs`): response envelope shapes / data contracts — inert data holders with no behavior beyond construction ([BR-CORE-004](business-rules.md#br-core-004-errorresponse-default-error-message)).
- `SAIF.API.Exceptions` namespace (`SAIFException.cs`): the exception hierarchy — supplies only the vocabulary/types for HTTP-failure signaling; contains no logic that inspects an `HttpStatusCode` and selects an exception type ([BR-CORE-001](business-rules.md#br-core-001-invaliddataexception-validation-failure-projection), [BR-CORE-002](business-rules.md#br-core-002-httpstatuscode-carried-by-every-saifexception-subtype), [BR-CORE-003](business-rules.md#br-core-003-fixed-default-exception-messages)).
- `SAIF.Web.API.Core` namespace (`BuildInfo.cs`): a single static-utility class for build/version-metadata file parsing, unrelated in purpose to the response/exception types; its co-location in this project is organizational/historical rather than architecturally cohesive*.

## Interaction model
- This library has zero outbound project dependencies (no `<ProjectReference>` elements).
- It is depended upon only by [SAIF.Web.API.Clients](../saif-web-api-clients/overview.md) within this repository, one-directionally, via a `<ProjectReference>` in `SAIF.Web.API.Clients.csproj`. `Clients` consumes `ApiResponse<T>` (in its `JsonHttpClient`) and the `SAIF.API.Exceptions.*` types (in its `ExceptionHandler.ToKnownError`).
- Despite being two separate assemblies/projects, `SAIF.Web.API.Core` and `SAIF.Web.API.Clients` ship and version as one logical distributable unit: the `Clients` package pipeline packs both `SAIF.Web.API.Core.dll`/`.pdb` and `SAIF.Web.API.Clients.dll`/`.pdb` into `lib\net45` via `IncludeReferencedProjects=true`. `SAIF.Web.API.Core` has no nuspec, pipeline, or `AppName` identity of its own.
- No caller of `BuildInfo.GetBuildInfo` or any constructor of `ErrorResponse` was found within this project or within `SAIF.Web.API.Clients`'s scanned source — these two types may be consumed by downstream applications outside this repository's scanned scope, or may be effectively vestigial within the packages examined*.

## Architecture diagram
The following diagram shows how SAIF.Web.API.Core's namespaces relate to the downstream consumer and how the two projects are packaged together.

```mermaid
flowchart TD
	Responses["SAIF.API.Responses<br>ApiResponse&lt;T&gt;,<br>ErrorResponse"]
	Exceptions["SAIF.API.Exceptions<br>SAIFException hierarchy"]
	BuildInfoNs["SAIF.Web.API.Core<br>BuildInfo"]
	Clients["SAIF.Web.API.Clients<br>JsonHttpClient,<br>ExceptionHandler"]
	Pkg["SAIF.Web.API.Clients<br>NuGet package<br>lib/net45 (bundles both<br>assemblies)"]

	Clients -->|"ProjectReference,<br>consumes<br>ApiResponse&lt;T&gt;"| Responses
	Clients -->|"ProjectReference,<br>consumes SAIFException<br>subtypes"| Exceptions
	BuildInfoNs -.->|"no in-repo caller found"| Clients

	Responses --> Pkg
	Exceptions --> Pkg
	BuildInfoNs --> Pkg
	Clients --> Pkg
```

## Sequence diagram
The following diagram shows the primary error-signaling flow: `SAIF.Web.API.Clients` catches an HTTP failure and raises a typed exception defined in this library.

```mermaid
sequenceDiagram
	participant Caller
	participant JsonHttpClient as "SAIF.Web.API.Clients.JsonHttpClient"
	participant ExceptionHandler as "SAIF.Web.API.Clients.ExceptionHandler"
	participant SAIFException as "SAIF.API.Exceptions.SAIFException subtype"

	Caller->>JsonHttpClient: Issue HTTP request
	JsonHttpClient-->>JsonHttpClient: "Receive ApiResponse<T> or error status"
	JsonHttpClient->>ExceptionHandler: ToKnownError(status)
	ExceptionHandler->>SAIFException: Construct typed exception, set HttpStatusCode
	SAIFException-->>Caller: Thrown to caller as strongly-typed exception
```

## Design constraints
- This library has no `<ProjectReference>` elements and no independent package/nuspec/pipeline identity — it is only ever distributed bundled inside the `SAIF.Web.API.Clients` NuGet package via `IncludeReferencedProjects=true`; any change to its packaging must be made through the `Clients` pipeline (`pipelines/build-webapiclients.yml` / `build-vars-webapiclients.yml`).
- The assembly name and root namespace are `SAIF.Web.API.Core`, but the DTO/exception types live under the shorter `SAIF.API.Responses` / `SAIF.API.Exceptions` namespaces rather than under `SAIF.Web.API.Core.*` — a structural naming mismatch with no behavioral effect, worth preserving for documentation clarity.
- `SAIF.API.Exceptions.UnauthorizedAccessException` shadows the BCL `System.UnauthorizedAccessException` short name; consumer code must fully qualify or alias to disambiguate.
- No configuration (`App.config`/`Web.config` or `ConfigurationManager` usage) exists anywhere in this project; `BuildInfo.GetBuildInfo`'s directory/pattern parameters are caller-supplied method arguments, not configuration.
- No security/authorization logic, cryptography, or credential handling is implemented in this library; `UnauthorizedAccessException` is a named signal type only.
- No database interaction of any kind occurs in this library.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [API reference](api/index.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts.

## Sources
- `src/SAIF.Web.API.Core/SAIF.Web.API.Core.csproj`
- `src/SAIF.Web.API.Core/ApiResponse.cs`
- `src/SAIF.Web.API.Core/BuildInfo.cs`
- `src/SAIF.Web.API.Core/ErrorResponse.cs`
- `src/SAIF.Web.API.Core/SAIFException.cs`
- `src/SAIF.Web.API.Core/Properties/AssemblyInfo.cs`
- `src/SAIF.Web.API.Clients/SAIF.Web.API.Clients.csproj`
- `pipelines/build-vars-webapiclients.yml`
- `pipelines/build-webapiclients.yml`
- `nuspec/SAIF.Web.API.Clients/SAIF.Web.API.Clients.nuspec`
