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

# SAIF.Web.API.Clients.35 architecture

`SAIF.Web.API.Clients.35` is a client-side integration/infrastructure library — the outbound HTTP client half of the SAIF Web API framework — that issues JSON requests to SAIF Web APIs and returns a typed result or a typed exception. It contains no business domain logic, no UI, and no persistence. The project is a `.NET Framework v3.5` "shadow" build of the sibling `SAIF.Web.API.Clients` project: its folder holds no `.cs` files of its own, compiling instead the sibling project's source via `<Compile Include>` linked-file items. The project is not a member of `src/SAIF.Web.API.Clients.sln`, and its output is referenced only by commented-out entries in the shipped nuspec, so the evidence indicates a **retired/dormant legacy variant** retained in source but no longer built or packaged.

## Responsibilities
- Given a base URI, caller identity (`ClientInfo`), and an authenticator, issue a JSON HTTP request to a SAIF Web API and return a typed result (`GetResult<T>`), a typed result array (`GetResults<T>`), or a full response envelope (`GetResponse<T>`, `PostJson<T>`, `PutJson<T>`, `PatchJson<T>`, `DeleteJson<T>`).
- Serialize outbound request bodies and deserialize inbound JSON payloads using a Newtonsoft-based `JsonSerializer` with configurable `DateTimeZoneHandling`.
- Translate unsuccessful HTTP responses into a typed `SAIFException` subtype (`ExceptionHandler`), sourced from `SAIF.Web.API.Core`'s exception taxonomy.
- Optionally propagate identity headers on every request (`Client-Name`, `Application-ID`, `Client-User`) and, when configured, an on-behalf-of impersonation header.
- Retry transient failures (default: transport failure/502/503/401) up to 3 times with a configurable delay before surfacing an error.

## Component boundaries
- **Public façade (`JsonHttpClient`):** verb-specific entry points (`GetResult`, `GetResults`, `GetResponse`, `PostJson`, `PutJson`, `PatchJson`, `DeleteJson`) — the only public API surface consumers use directly.
- **Request construction / transport (`JsonHttpClient.GetJsonResponse`, private):** RestClient/RestRequest assembly, header injection, authenticator attachment, retry loop, and timeout handling.
- **Serialization (`JsonSerializer`, `JsonHttpClient.GetContentArray<T>`):** Newtonsoft-based JSON ⇄ CLR conversion honoring the configured `DateTimeZoneHandling`.
- **Error translation (`ExceptionHandler`):** maps HTTP status code + response body to a specific `SAIFException` subtype.
- **Data carriers (`ClientInfo`, `EnvironmentSetting` public; `JsonResponse` internal):** immutable/POCO state passed between the layers above. `EnvironmentSetting` is not referenced by any other type in this library's compiled scope — it is an unused public DTO here.*

## Interaction model
- **Outbound boundary:** HTTP(S) to a SAIF Web API, via RestSharp. The base URI is supplied entirely by the caller (`Uri serviceBaseUri`); the library contains no endpoint literals.
- **Contract boundary:** `SAIF.Web.API.Core` defines the shared response envelope (`ApiResponse<T>`) and exception taxonomy (`SAIF.API.Exceptions.*`) used on both the service and client side — the coupling point that keeps client and server error semantics aligned.
- **Ambient-context boundary (leaky):** when `SetOnBehalfOfUserHeaders` is true, `JsonHttpClient` reads `System.Web.HttpContext.Current`, binding an otherwise transport-neutral library to an ASP.NET hosting context. In this .35 project the supporting `HttpContextExtensions.cs` source file is excluded from compilation and `System.Web` is not referenced, so this path has no working implementation in the net3.5 variant.

## Architecture diagram
The following diagram shows the high-level component interactions for the .35 variant, including its coupling to the sibling source project and its outbound call chain to the remote API.

```mermaid
flowchart TD
	Caller["Calling application"] --> Facade["JsonHttpClient<br>(public facade)"]
	Facade --> Transport["GetJsonResponse<br>(request<br>construction/transport)"]
	Transport --> Serializer["JsonSerializer<br>(Newtonsoft-based)"]
	Transport --> RestSharpLib["RestSharp 105.2.3<br>(external package)"]
	RestSharpLib --> RemoteApi["SAIF Web API<br>(caller-supplied base<br>URI)"]
	Transport --> ErrorHandler["ExceptionHandler<br>(HTTP status to<br>SAIFException)"]
	LinkedSource["Linked source from<br>SAIF.Web.API.Clients<br>(no .cs files owned<br>locally)"] -.compiles into.-> Facade
```

The following diagram shows the shared contract boundary: both the public facade and the error handler depend on `SAIF.Web.API.Core` for the response envelope and exception taxonomy used by both the client and the server.

```mermaid
flowchart TD
	Facade["JsonHttpClient<br>(public facade)"] --> CoreLib["SAIF.Web.API.Core<br>(ApiResponse&lt;T&gt;,<br>SAIFException hierarchy)"]
	ErrorHandler["ExceptionHandler<br>(HTTP status to<br>SAIFException)"] --> CoreLib
```

## Sequence diagram
The following diagram shows the primary request/response sequence for a write operation (for example `PostJson<T>`), including the retry and error-translation steps.

```mermaid
sequenceDiagram
	participant Caller
	participant JsonHttpClient
	participant RestSharp
	participant SAIFWebAPI as SAIF Web API
	participant ExceptionHandler
	Caller->>JsonHttpClient: PostJson<T>(uriSegment, body)
	JsonHttpClient->>JsonHttpClient: Build RestRequest + identity headers
	JsonHttpClient->>RestSharp: Execute(request)
	RestSharp->>SAIFWebAPI: HTTP request
	SAIFWebAPI-->>RestSharp: HTTP response
	RestSharp-->>JsonHttpClient: IRestResponse
	alt retryable status and retries remain
		JsonHttpClient->>JsonHttpClient: Sleep(RetryDelayInMs), retry
	end
	JsonHttpClient->>ExceptionHandler: EnsureSuccessfulResponse(response)
	alt status 200-399
		ExceptionHandler-->>JsonHttpClient: return normally
		JsonHttpClient-->>Caller: ApiResponse<T>
	else status <200 or >=400
		ExceptionHandler-->>JsonHttpClient: throw SAIFException subtype
		JsonHttpClient-->>Caller: exception propagated
	end
```

## Design constraints
- **Dormant/retired legacy variant.** The project has no source files of its own (links compile from the sibling `SAIF.Web.API.Clients` folder), is absent from `src/SAIF.Web.API.Clients.sln` (so CI never builds it), and its output is referenced only by commented-out `<file>` entries in `nuspec/SAIF.Web.API.Clients/SAIF.Web.API.Clients.nuspec` — the net35 assembly is not shipped by the current package definition.
- **Cross-framework project reference mismatch.** This project targets `.NET Framework v3.5` but its only in-repo dependency, `SAIF.Web.API.Core`, targets `v4.6.2`; a net4.6.2 assembly cannot be referenced from a net3.5 assembly.
- **Excluded on-behalf-of implementation.** `JsonHttpClient.cs` declares `using SAIF.Web.API.Clients.Extensions;` and calls `HttpContext.Current.DomainlessUser()`, but `Extensions/HttpContextExtensions.cs` is deliberately excluded from this project and `System.Web` is not referenced — the on-behalf-of impersonation path (`SetOnBehalfOfUserHeaders`) has no compilable implementation in this variant.
- **RestSharp namespace drift.** The linked source imports `RestSharp.Serialization.Json`, a namespace introduced in the RestSharp 106.x line, while this project pins RestSharp 105.2.3 via `packages.config` — the namespace is not expected to exist in the pinned assembly, compounding the build-viability concern.
- **Dependency version divergence from the net4.6.2 sibling.** `RestSharp` (105.2.3 vs 106.12.0) and `SAIF.Framework.Common` (1.0.17234.2 vs 2.0.22074.3, a major-version gap) are pinned to older versions than the actively-built sibling project.
- **No assembly-level attributes compiled.** The excluded `Properties/AssemblyInfo.cs` leaves only an empty `Properties\` folder declared in the project, so no assembly-level attributes are compiled into the net35 output.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [API reference](api/index.md)
- [SAIF.Web.API.Core overview](../saif-web-api-core/overview.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.Clients.35/SAIF.Web.API.Clients.35.csproj
- src/SAIF.Web.API.Clients.35/packages.config
- src/SAIF.Web.API.Clients/JsonHttpClient.cs
- src/SAIF.Web.API.Clients/ClientInfo.cs
- src/SAIF.Web.API.Clients/ExceptionHandler.cs
- src/SAIF.Web.API.Clients/JsonSerializer.cs
- src/SAIF.Web.API.Clients/JsonResponse.cs
- src/SAIF.Web.API.Clients/EnvironmentSetting.cs
- src/SAIF.Web.API.Clients/Extensions/HttpContextExtensions.cs (excluded from this project)
- src/SAIF.Web.API.Core/SAIF.Web.API.Core.csproj
- src/SAIF.Web.API.Clients.sln
- nuspec/SAIF.Web.API.Clients/SAIF.Web.API.Clients.nuspec
