refactor(server)!: XRPC endpoint hosting — route groups, one NSID source, correct binding #121

Closed
opened 2026-09-24 12:39:05 +00:00 by Grandiras · 0 comments
Owner

Part of the v0.7.0 update cycle (wave 4). Server-side XRPC hosting (ATProtoNet.Server/Xrpc).

Scope

  • MapXrpcEndpoints() returns a RouteGroupBuilder under /xrpc, so .RequireAuthorization(), rate limiting and metadata conventions apply. Per-handler [Authorize] is honoured.
  • One source of truth for an endpoint's NSID: static abstract Nsid Nsid on IXrpcEndpoint, or the attribute only. Remove the RuntimeHelpers.GetUninitializedObject trick, which fails for auto-property and field initializers. AddXrpcEndpoint<T> and assembly scanning must agree.
  • Bind query parameters by the target property type. Today a single ?uris=x fails to bind to List<string>. Also remove the per-request Dictionary→JSON→TParams round trip, and accept repeated keys (plus foo[]= leniently, as xrpc-server does).
  • One exception filter maps every exception to the XRPC error envelope (InternalServerError for unknown ones), with a typed XrpcErrorBody instead of anonymous objects.
  • Interface gaps: a procedure with no input (IXrpcProcedure<TOut>), and a procedure with binary input (Stream + content type, for blob-upload-style methods).
  • Collapse the 5 near-identical reflection wrappers and the dead registry Kind into one generic registration path (friendlier to trimming).
  • Update the Spaces endpoints to the new shape; today each declares its NSID twice.

CHANGELOG Breaking changes (how endpoints declare their NSID, the return type of MapXrpcEndpoints) plus Fixed (single-value arrays, error envelope).

Part of the v0.7.0 update cycle (wave 4). Server-side XRPC hosting (`ATProtoNet.Server/Xrpc`). ## Scope - [ ] `MapXrpcEndpoints()` returns a `RouteGroupBuilder` under `/xrpc`, so `.RequireAuthorization()`, rate limiting and metadata conventions apply. Per-handler `[Authorize]` is honoured. - [ ] One source of truth for an endpoint's NSID: `static abstract Nsid Nsid` on `IXrpcEndpoint`, or the attribute only. Remove the `RuntimeHelpers.GetUninitializedObject` trick, which fails for auto-property and field initializers. `AddXrpcEndpoint<T>` and assembly scanning must agree. - [ ] Bind query parameters by the **target property type**. Today a single `?uris=x` fails to bind to `List<string>`. Also remove the per-request `Dictionary`→JSON→`TParams` round trip, and accept repeated keys (plus `foo[]=` leniently, as `xrpc-server` does). - [ ] One exception filter maps **every** exception to the XRPC error envelope (`InternalServerError` for unknown ones), with a typed `XrpcErrorBody` instead of anonymous objects. - [ ] Interface gaps: a procedure with no input (`IXrpcProcedure<TOut>`), and a procedure with binary input (`Stream` + content type, for blob-upload-style methods). - [ ] Collapse the 5 near-identical reflection wrappers and the dead registry `Kind` into one generic registration path (friendlier to trimming). - [ ] Update the Spaces endpoints to the new shape; today each declares its NSID twice. CHANGELOG `Breaking changes` (how endpoints declare their NSID, the return type of `MapXrpcEndpoints`) plus `Fixed` (single-value arrays, error envelope).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/ATProto.NET#121
No description provided.