Refine public documentation

This commit is contained in:
2026-08-16 23:58:16 +10:00
parent 464b514f5c
commit f07c08df17
15 changed files with 57 additions and 67 deletions
+4 -5
View File
@@ -20,12 +20,11 @@ dotnet format tests/BinaryLane.Api.Tests/BinaryLane.Api.Tests.csproj --verify-no
dotnet format examples/BinaryLane.Api.Demo/BinaryLane.Api.Demo.csproj --verify-no-changes --no-restore dotnet format examples/BinaryLane.Api.Demo/BinaryLane.Api.Demo.csproj --verify-no-changes --no-restore
``` ```
Run these commands sequentially. Do not run separate restore, build, test, or Run these commands one at a time. The serial options keep local build resource
pack commands concurrently on the same checkout. use predictable on a shared checkout.
The tracked demo application lives in The tracked demo application lives in `examples/BinaryLane.Api.Demo`. It reads
`examples/BinaryLane.Api.Demo`. Configure a personal API token with user `BinaryLane:ApiToken` from its configuration providers, including user secrets.
secrets; never put it in a file, test fixture, issue, pull request, or commit.
```bash ```bash
dotnet user-secrets set \ dotnet user-secrets set \
+6 -7
View File
@@ -10,8 +10,8 @@ balancers, VPCs, and other v2 resources.
See the [BinaryLane API reference](https://api.binarylane.com.au/reference/) for See the [BinaryLane API reference](https://api.binarylane.com.au/reference/) for
provider-specific API behaviour. provider-specific API behaviour.
BinaryLane describes its API as a developer preview. Pin the package version BinaryLane describes its API as a developer preview. SDK releases track the
used by production applications and review release notes before upgrading. committed upstream contract independently of the provider's reference version.
> This project is not affiliated with, endorsed by, or supported by BinaryLane. > This project is not affiliated with, endorsed by, or supported by BinaryLane.
> For account or infrastructure support, use > For account or infrastructure support, use
@@ -27,8 +27,8 @@ Remove `--prerelease` once a stable package version is available.
## Quick start ## Quick start
Keep the API token in a secret store, user secrets, or an environment variable. The registration below reads `BinaryLane:ApiToken` from application
Do not commit it to configuration or source control. configuration and otherwise uses `BINARYLANE_API_TOKEN`.
```csharp ```csharp
using BinaryLane.Api.V2; using BinaryLane.Api.V2;
@@ -65,8 +65,7 @@ static async Task ListServersAsync(
} }
``` ```
List methods support `CancellationToken`. Mutating calls are sent once; add a All asynchronous resource methods accept a `CancellationToken`.
retry policy only when the operation is known to be safe to repeat.
## Documentation ## Documentation
@@ -76,7 +75,7 @@ retry policy only when the operation is known to be safe to repeat.
| [Configuration](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/configuration.md) | Tokens, timeouts, direct construction, and HTTP configuration. | | [Configuration](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/configuration.md) | Tokens, timeouts, direct construction, and HTTP configuration. |
| [Pagination](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/pagination.md) | Working with pages or async enumeration. | | [Pagination](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/pagination.md) | Working with pages or async enumeration. |
| [Actions](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/actions-and-polling.md) | Submitting and optionally waiting for server actions. | | [Actions](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/actions-and-polling.md) | Submitting and optionally waiting for server actions. |
| [Error handling](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/errors.md) | Handling API failures safely. | | [Error handling](https://github.com/alexhopeoconnor/binarylane-dotnet/blob/main/docs/errors.md) | HTTP exceptions and diagnostic information. |
| [Demo](https://github.com/alexhopeoconnor/binarylane-dotnet/tree/main/examples/BinaryLane.Api.Demo) | Running the included read-only console app. | | [Demo](https://github.com/alexhopeoconnor/binarylane-dotnet/tree/main/examples/BinaryLane.Api.Demo) | Running the included read-only console app. |
## Compatibility ## Compatibility
-3
View File
@@ -43,6 +43,3 @@ if (action.Status == BinaryLaneValues.ActionStatus.Completed)
// Continue with the next step. // Continue with the next step.
} }
``` ```
If an action request has an uncertain outcome, retrieve the action or server
state before submitting it again.
+2 -2
View File
@@ -10,8 +10,8 @@ version change.
The raw document contains virtual paths such as The raw document contains virtual paths such as
`/v2/servers/{server_id}/actions#PowerOn`. These are API-reference aliases for `/v2/servers/{server_id}/actions#PowerOn`. These are API-reference aliases for
action payload variants, not real HTTP routes. Coverage and generated-code action payload variants, not real HTTP routes. Coverage checks and route
checks must use the normalized contract and count only the real reviews use the normalized contract and count only the real
`POST /v2/servers/{server_id}/actions` route. `POST /v2/servers/{server_id}/actions` route.
| API area | Public resource boundary | | API area | Public resource boundary |
+11 -10
View File
@@ -3,24 +3,25 @@
## Standard registration ## Standard registration
In an ASP.NET Core or generic-host application, `AddBinaryLaneApi` configures In an ASP.NET Core or generic-host application, `AddBinaryLaneApi` configures
`IBinaryLaneClient` and the individual resource interfaces. `IBinaryLaneClient`, individual resource interfaces, and the underlying typed
`HttpClient`.
```csharp ```csharp
builder.Services.AddBinaryLaneApi(options => builder.Services.AddBinaryLaneApi(options =>
{ {
options.ApiToken = builder.Configuration["BinaryLane:ApiToken"]; options.ApiToken = builder.Configuration["BinaryLane:ApiToken"];
options.RequestTimeoutSeconds = 100;
}); });
``` ```
| Setting | Default | Description | | Setting | Default | Description |
| --- | --- | --- | | --- | --- | --- |
| `BaseUrl` | `https://api.binarylane.com.au/` | API base address. Leave unchanged for BinaryLane's public API. | | `BaseUrl` | `https://api.binarylane.com.au/` | Root URI used for API requests. |
| `ApiToken` | none | Bearer token used by the default provider. | | `ApiToken` | none | Bearer token used by the default provider. |
| `RequestTimeoutSeconds` | `100` | Timeout for an individual HTTP request. | | `RequestTimeoutSeconds` | `100` | Timeout for an individual HTTP request. |
The base URL must be an HTTPS URL without credentials, a query string, or a `BaseUrl` must be an HTTPS URL without credentials, a query string, or a
fragment. Options are validated when the application starts. fragment. `BaseUrl` and `RequestTimeoutSeconds` are validated when the host
starts; request timeouts can range from 1 to 300 seconds.
## Rotating tokens ## Rotating tokens
@@ -36,7 +37,7 @@ builder.Services.AddSingleton<IBinaryLaneTokenProvider, VaultTokenProvider>();
builder.Services.AddBinaryLaneApi(options => options.RequestTimeoutSeconds = 100); builder.Services.AddBinaryLaneApi(options => options.RequestTimeoutSeconds = 100);
``` ```
The provider is called for every request. Do not log the returned token. The provider is called for every outgoing request.
## Use without dependency injection ## Use without dependency injection
@@ -63,10 +64,10 @@ var client = new BinaryLaneClient(
telemetry, or other application-specific handlers. telemetry, or other application-specific handlers.
```csharp ```csharp
builder.Services.AddBinaryLaneApi(options => options.ApiToken = token) builder.Services.AddBinaryLaneApi(options =>
options.ApiToken = builder.Configuration["BinaryLane:ApiToken"])
.ConfigureHttpClient(client => client.DefaultRequestHeaders.Add("X-App", "my-service")); .ConfigureHttpClient(client => client.DefaultRequestHeaders.Add("X-App", "my-service"));
``` ```
Only add automatic retries when the request is safe to repeat. In particular, The client does not apply retries itself. Applications can add their own
POST, PUT, PATCH, and DELETE requests may have already been applied when a handlers through the returned `IHttpClientBuilder`.
network failure is reported.
+11 -9
View File
@@ -1,13 +1,15 @@
# Error handling # Error handling
All API failures derive from `BinaryLaneApiException`. `BinaryLaneApiException` represents a non-success response from the BinaryLane
API. Network, timeout, cancellation, and client-configuration failures use
their standard .NET exception types.
| Exception | When it is used | | Exception | When it is used |
| --- | --- | | --- | --- |
| `BinaryLaneUnauthorizedException` | The token is missing, invalid, or expired. | | `BinaryLaneUnauthorizedException` | BinaryLane returned HTTP 401. |
| `BinaryLaneForbiddenException` | The token does not have access to the resource. | | `BinaryLaneForbiddenException` | BinaryLane returned HTTP 403. |
| `BinaryLaneNotFoundException` | The requested resource does not exist or is not visible to the token. | | `BinaryLaneNotFoundException` | BinaryLane returned HTTP 404. |
| `BinaryLaneValidationException` | BinaryLane rejected the request payload. | | `BinaryLaneValidationException` | BinaryLane returned HTTP 400 or 422. |
| `BinaryLaneApiException` | Any other non-success HTTP response. | | `BinaryLaneApiException` | Any other non-success HTTP response. |
```csharp ```csharp
@@ -32,9 +34,9 @@ catch (BinaryLaneApiException exception)
``` ```
Each exception provides `StatusCode`, `RequestUri`, `Headers`, and, when Each exception provides `StatusCode`, `RequestUri`, `Headers`, and, when
available, `Problem` and `ResponseBody`. Provider detail text can contain user available, `Problem` and `ResponseBody`. `ResponseBody` contains at most the
data. Do not write `Problem`, `Headers`, or `ResponseBody` to application logs first 32,768 characters of diagnostic text, followed by an ellipsis when
without appropriate redaction. truncated.
Successful JSON responses are limited to 16 MiB. A larger response throws Successful response bodies are limited to 16 MiB. A larger response throws
`HttpRequestException` before the client buffers it in memory. `HttpRequestException` before the client buffers it in memory.
+8 -6
View File
@@ -9,25 +9,24 @@
dotnet add package BinaryLane.Api --prerelease dotnet add package BinaryLane.Api --prerelease
``` ```
## 2. Store the token safely ## 2. Configure the API token
For local development, initialise user secrets for your application and add For local development, .NET user secrets can provide the
the token: `BinaryLane:ApiToken` configuration value:
```bash ```bash
dotnet user-secrets init dotnet user-secrets init
dotnet user-secrets set "BinaryLane:ApiToken" "your-token" dotnet user-secrets set "BinaryLane:ApiToken" "your-token"
``` ```
For hosted applications, use the platform's secret store or supply The registration below reads that value first, then falls back to
`BINARYLANE_API_TOKEN` at runtime. `BINARYLANE_API_TOKEN`.
## 3. Register the client ## 3. Register the client
```csharp ```csharp
using BinaryLane.Api.V2; using BinaryLane.Api.V2;
using BinaryLane.Api.V2.DependencyInjection; using BinaryLane.Api.V2.DependencyInjection;
using BinaryLane.Api.V2.Models;
builder.Services.AddBinaryLaneApi(options => builder.Services.AddBinaryLaneApi(options =>
{ {
@@ -42,6 +41,9 @@ builder.Services.AddBinaryLaneApi(options =>
Inject `IBinaryLaneClient`, then select the resource you need: Inject `IBinaryLaneClient`, then select the resource you need:
```csharp ```csharp
using BinaryLane.Api.V2;
using BinaryLane.Api.V2.Models;
public sealed class ServerReader(IBinaryLaneClient binaryLane) public sealed class ServerReader(IBinaryLaneClient binaryLane)
{ {
public IAsyncEnumerable<Server> ListAsync(CancellationToken cancellationToken) => public IAsyncEnumerable<Server> ListAsync(CancellationToken cancellationToken) =>
+1 -2
View File
@@ -27,5 +27,4 @@ await foreach (var server in client.Servers.ListAllAsync(cancellationToken: canc
} }
``` ```
Pass a cancellation token from the calling request, worker, or command so a The cancellation token is carried across page requests made by `ListAllAsync`.
stopped operation does not continue fetching pages.
+5 -4
View File
@@ -57,7 +57,8 @@ section for release notes.
## Recovery ## Recovery
NuGet packages cannot be overwritten. If a release has a packaging defect, NuGet packages cannot be overwritten. If a published release has a packaging
unlist it if appropriate, publish a new version, and document the correction defect, unlist it if appropriate, publish a new version, and document the
in the changelog. Do not retag a version or attempt to reuse a published correction in the changelog. A tag can be replaced only before the workflow
package version. publishes its matching NuGet version; published package versions are never
reused.
+1 -2
View File
@@ -28,8 +28,7 @@ snapshot makes those changes visible during SDK maintenance.
The raw document includes virtual `#ActionName` paths for individual server The raw document includes virtual `#ActionName` paths for individual server
action variants. They exist to improve the provider's reference UI but are not action variants. They exist to improve the provider's reference UI but are not
HTTP paths. `eng/normalize-openapi.sh` strips them when producing a normalized HTTP paths. `eng/normalize-openapi.sh` strips them when producing a normalized
document for code generation or coverage checks. Do not issue requests to document for route and coverage validation.
those virtual paths.
## Monitoring and updating ## Monitoring and updating
+3 -5
View File
@@ -44,7 +44,7 @@ internal static class DemoProgram
{ {
Console.Error.WriteLine( Console.Error.WriteLine(
"No API token is configured. Use user secrets or set BINARYLANE_API_TOKEN. " "No API token is configured. Use user secrets or set BINARYLANE_API_TOKEN. "
+ "Run with --help for a safe setup command."); + "Run with --help for a setup command.");
return 2; return 2;
} }
@@ -104,8 +104,7 @@ internal static class DemoProgram
} }
catch (BinaryLaneApiException exception) catch (BinaryLaneApiException exception)
{ {
// Provider details may contain user data. Do not print Problem, headers, // The sample prints the response status and path only.
// or ResponseBody in a sample application.
Console.Error.WriteLine( Console.Error.WriteLine(
$"BinaryLane request failed with HTTP {(int)exception.StatusCode} " $"BinaryLane request failed with HTTP {(int)exception.StatusCode} "
+ $"({exception.StatusCode}) at {exception.RequestUri.AbsolutePath}."); + $"({exception.StatusCode}) at {exception.RequestUri.AbsolutePath}.");
@@ -160,8 +159,7 @@ internal static class DemoProgram
server <positive-server-id> server <positive-server-id>
regions regions
You can also set BINARYLANE_API_TOKEN for one process. Never commit You can also set BINARYLANE_API_TOKEN for one process.
a token or add it to appsettings.json.
"""); """);
} }
} }
+1 -2
View File
@@ -13,8 +13,7 @@ dotnet user-secrets set \
--project examples/BinaryLane.Api.Demo --project examples/BinaryLane.Api.Demo
``` ```
Alternatively, set `BINARYLANE_API_TOKEN` for one process. Do not add a token Alternatively, start the process with `BINARYLANE_API_TOKEN` set.
to `appsettings.json`.
## Run it ## Run it
@@ -11,10 +11,7 @@ public sealed class BinaryLaneOptions
/// <summary>The BinaryLane API root URL.</summary> /// <summary>The BinaryLane API root URL.</summary>
public string BaseUrl { get; set; } = "https://api.binarylane.com.au/"; public string BaseUrl { get; set; } = "https://api.binarylane.com.au/";
/// <summary> /// <summary>The bearer token used by the default token provider.</summary>
/// The bearer token to use when the default token provider is registered. Prefer a secret store,
/// user secrets, or environment-variable based configuration rather than committing this value.
/// </summary>
public string? ApiToken { get; set; } public string? ApiToken { get; set; }
/// <summary>Timeout applied to individual HTTP requests.</summary> /// <summary>Timeout applied to individual HTTP requests.</summary>
@@ -13,8 +13,8 @@ namespace BinaryLane.Api.V2.DependencyInjection;
public static class ServiceCollectionExtensions public static class ServiceCollectionExtensions
{ {
/// <summary> /// <summary>
/// Registers a typed BinaryLane client. The returned builder lets an application compose its /// Registers a typed BinaryLane client. The returned builder supports application-specific
/// own proxy, telemetry, and safe GET-only resilience handlers. /// HTTP client configuration.
/// </summary> /// </summary>
public static IHttpClientBuilder AddBinaryLaneApi( public static IHttpClientBuilder AddBinaryLaneApi(
this IServiceCollection services, this IServiceCollection services,
@@ -32,10 +32,7 @@ public class BinaryLaneApiException : Exception
/// <summary>Structured problem details, when BinaryLane supplied them.</summary> /// <summary>Structured problem details, when BinaryLane supplied them.</summary>
public BinaryLaneApiProblem? Problem { get; } public BinaryLaneApiProblem? Problem { get; }
/// <summary> /// <summary>Bounded raw response text for diagnostics.</summary>
/// Bounded raw response text for diagnostics. It omits request headers, but can contain
/// provider-supplied or user-provided data; avoid logging it indiscriminately.
/// </summary>
public string? ResponseBody { get; } public string? ResponseBody { get; }
/// <summary>Response and content headers.</summary> /// <summary>Response and content headers.</summary>