Architecture¶
PdfClient is a single, immutable-after-construction class that implements IPdfClient, wraps one SAIF.Web.API.Clients.JsonHttpClient field for its five remote members, and delegates its six local members to the static PdfAPI.Core.PdfClientService.
Architecture diagram¶
flowchart TD
CONSUMER[Consuming application] --> IFACE["IPdfClient interface"]
IFACE --> IMPL["PdfClient : IPdfClient"]
IMPL --> INFO["ClientInfo<br/>caller-supplied, not populated by PdfClient"]
IMPL --> HTTP["SAIF.Web.API.Clients.JsonHttpClient"]
IMPL --> LOCAL["PdfAPI.Core.PdfClientService<br/>6 non-HTTP members"]
HTTP --> URI["baseUri = url.TrimEnd('/') + '/v1/'"]
URI --> API["PdfAPI REST API"]
IMPL --> CONTRACTS["PdfAPI.Core contracts"]
API --> CONTRACTS
Component responsibilities¶
| Component | Type | Responsibility |
|---|---|---|
IPdfClient |
Interface | The public contract; declares 9 of the client's 11 public members |
PdfClient |
Class | Composes the relative URL per remote member, delegates to JsonHttpClient, and forwards local members to PdfClientService; also exposes IsPdfa and Track, which are on the concrete class only |
JsonHttpClient |
SAIF.Web.API.Clients |
Serialization, transport, timeout, and the PostJson/GetResult result envelope |
ClientInfo |
SAIF.Web.API.Clients |
Caller identity sent with each request; supplied by the caller, not built by PdfClient |
PdfAPI.Core |
Contracts assembly | Request and response DTOs shared with the API (ConvertRequest, MergeRequest, PdfResult, PdfTrackingInfo, PdfFormat, DocumentRange) |
PdfClientService |
Local service (PdfAPI.Core.Services) |
Backs the six non-HTTP members: Version, Pages, IsPdf, HasFormFields, Flatten, Extract |
Construction¶
PdfClient has exactly one public constructor and no separate initializer. There is no parameterless constructor and no two-phase initializer method — the client cannot be constructed in an uninitialized state, unlike a client with a separate initializer method taking a URL and timeout.
| Constructor / initializer | Parameters | Effect |
|---|---|---|
PdfClient(ClientInfo info, string url) |
info — caller-supplied identity; url — API base URL |
Builds baseUri from url and constructs the JsonHttpClient field, which is readonly |
| Parameterless constructor | — | Not present |
| Two-phase initializer method | — | Not present |
Base URI composition¶
var baseUri = new Uri($"{url.TrimEnd('/')}/v1/");
_jsonHttpClient = new JsonHttpClient(baseUri, info);
| Element | Value | Source |
|---|---|---|
| Base URL | Caller-supplied url constructor argument |
PdfAPI.Client\PdfClient.cs:15 |
| Version suffix | v1/ |
Hard-coded in PdfClient.cs:17 |
| Trailing-slash handling | url.TrimEnd('/') applied before appending /v1/ |
PdfAPI.Client\PdfClient.cs:17 |
Both http://host/pdfapi and http://host/pdfapi/ compose the same base URI. There is no guard on url itself: a null value throws NullReferenceException from TrimEnd, and an empty/relative value throws UriFormatException from the Uri constructor.
ClientInfo population¶
| Property | Value | Source |
|---|---|---|
ApplicationId |
Not set by PdfClient |
Caller-supplied info argument, used as-is |
MachineName |
Not set by PdfClient |
Caller-supplied info argument, used as-is |
UserId |
Not set by PdfClient |
Caller-supplied info argument, used as-is |
Every consumer observed in scope passes a default-constructed, empty ClientInfo (PdfApiClientTester\PdfApiClientTester\PdfTester.cs:23), so no application, machine, or user identity is populated by any caller in this repository.
Call pattern¶
Each remote member follows the same shape: compose a relative URL, call one JsonHttpClient method, and unwrap the result.
JsonHttpClient member |
Returns | Used by this client for |
|---|---|---|
GetResult<T>(url) |
T, returned directly with no unwrapping |
Track(long) only |
GetResults<T>(url) |
T[] |
Not used by this client |
PostJson<T>(url, body) |
Result envelope with .Results |
Convert (both overloads), Merge, IsPdfa — each unwraps with .Results.FirstOrDefault() |
An empty .Results collection from PostJson<T> silently yields default(T) — false for IsPdfa, null for Convert/Merge — with no exception raised. See Tech debt.
Design constraints¶
- No public constructor or member accepts a
CancellationToken; every remote call is fully synchronous and blocks the calling thread for the HTTP round trip. - The single constructor makes
_jsonHttpClientareadonlyfield assigned once, so an instance is immutable and has no shared mutable state after construction. - The vestigial
private readonly string _pdfRootDirectory;field (PdfClient.cs:13) is declared but never assigned or read.
Inherited framework behavior¶
Serialization, request composition, timeout enforcement, and the PostJson/GetResult result envelope are implemented inside SAIF.Web.API.Clients.JsonHttpClient and are not re-documented here.
Related documentation¶
- Client index
- Overview
- Package
- Client reference
- Endpoint map
- Consumption
- Contracts
- Dependencies
- Business rules
- Tech debt
Sources¶
PdfAPI.Client\PdfClient.csPdfAPI.Client\IPdfClient.csPdfAPI.Core\Services\PdfClientService.cs