![]() |
VOOZH | about |
dotnet add package Rystem.Api --version 10.0.8
NuGet\Install-Package Rystem.Api -Version 10.0.8
<PackageReference Include="Rystem.Api" Version="10.0.8" />
<PackageVersion Include="Rystem.Api" Version="10.0.8" />Directory.Packages.props
<PackageReference Include="Rystem.Api" />Project file
paket add Rystem.Api --version 10.0.8
#r "nuget: Rystem.Api, 10.0.8"
#:package Rystem.Api@10.0.8
#addin nuget:?package=Rystem.Api&version=10.0.8Install as a Cake Addin
#tool nuget:?package=Rystem.Api&version=10.0.8Install as a Cake Tool
Rystem.Api is the shared metadata package behind the Api area.
It does not expose routes by itself and it does not create HTTP clients by itself. Instead, it records endpoint definitions from interfaces so that:
Rystem.Api.Server can map them as minimal APIsRystem.Api.Client can create runtime HTTP proxies from the same definitionsdotnet add package Rystem.Api
| Package | Role |
|---|---|
Rystem.Api |
shared endpoint metadata, binding attributes, IHttpFile, and builder APIs |
Rystem.Api.Server |
ASP.NET Core mapping, OpenAPI, Swagger, Scalar |
Rystem.Api.Client |
runtime DispatchProxy HTTP clients |
Rystem.Api.Client.Authentication.BlazorServer |
request enhancers for Blazor Server token flows |
Rystem.Api.Client.Authentication.BlazorWasm |
request enhancers for Blazor WebAssembly token flows |
The core flow is:
ConfigureEndpoints(...) once to set shared defaultsAddEndpoint<T>(...) or AddEndpointWithFactory<T>(...) to record API metadataRystem.Api.Server map those endpoints with UseEndpointApi()Rystem.Api.Client build proxies from the same endpoint registrationsInternally, endpoint definitions are stored in a singleton EndpointsManager.
Because of that, shared configuration should be done before or together with endpoint registration. In practice, treat ConfigureEndpoints(...) as startup configuration, not something to call later.
This pattern is what the sample domain project does in src/Api/Test/Rystem.Api.Test.Domain/ServiceCollectionExtensions.cs.
services
.ConfigureEndpoints(options =>
{
options.BasePath = "rapi/";
})
.AddEndpoint<ISalubry>(endpoint =>
{
endpoint.SetEndpointName("Salubriend");
endpoint.AddAuthorizationForAll("policy");
});
That registration is shared metadata. You still need:
UseEndpointApi() from Rystem.Api.ServerAddClientsForAllEndpointsApi(...) or AddClientForEndpointApi<T>(...) from Rystem.Api.ClientEndpointsManager defaults are:
| Setting | Default |
|---|---|
BasePath |
api/ |
RemoveAsyncSuffix |
true |
EndpointValue defaults are:
IAsyncSo this interface:
public interface IProductService
{
Task<Product?> GetAsync(string id);
}
becomes this route shape by default:
api/ProductService/Get?id=...
If a method has path-bound parameters, the placeholders are appended after the method segment.
| Method | Purpose |
|---|---|
ConfigureEndpoints(Action<EndpointsManager>) |
configure shared defaults like BasePath and async-suffix trimming |
AddEndpoint<T>(Action<ApiEndpointBuilder<T>>, name?) |
register one interface as one endpoint set |
AddEndpointWithFactory<T>(Action<ApiEndpointBuilder<T>>?) |
declare a factory-backed endpoint set to be expanded server-side |
The optional name on AddEndpoint<T>(..., name) targets a specific named factory instance.
On the server, that means the endpoint is resolved through IFactory<T>. On the client, the matching named proxy is also a factory-backed registration rather than a plain default interface registration.
ApiEndpointBuilder<T>The actual public builder surface is:
| Method | Purpose |
|---|---|
SetEndpointName(name) |
override the endpoint segment |
SetMethodName(expr, name) |
rename a method by expression |
SetMethodName(methodInfo, name) |
rename a method by MethodInfo |
Remove(methodInfo) |
exclude a method |
Remove(methodName) |
exclude a method by stored key |
AddAuthorization(expr) |
require authenticated access on one method |
AddAuthorization(expr, params policies) |
require named policies on one method |
AddAuthorizationForAll() |
require authentication on all methods |
AddAuthorizationForAll(params policies) |
require named policies on all methods |
SetupParameter(expr, parameterName, setup) |
override parameter metadata by expression |
SetupParameter(methodInfo, parameterName, setup) |
override parameter metadata by MethodInfo |
The expression-based lookup methods are less reliable when RemoveAsyncSuffix = true, because route names and expression names can diverge.
For async methods, prefer the MethodInfo overloads when you need precise customization.
Example:
var getMethod = typeof(ISalubry).GetMethod(nameof(ISalubry.GetAsync))!;
services.AddEndpoint<ISalubry>(endpoint =>
{
endpoint.SetEndpointName("Salubriend");
endpoint.SetMethodName(getMethod, "Gimme");
endpoint.SetupParameter(getMethod, "id", parameter =>
{
parameter.Location = ApiParameterLocation.Body;
parameter.Example = 56;
});
});
These attributes are the shared binding contract for both server and client packages.
| Attribute | Meaning |
|---|---|
[Query] |
bind from query string |
[Path(Index = n)] |
bind from path segments |
[Header] |
bind from request headers |
[Cookie] |
bind from cookies |
[Body] |
bind from request body |
[Form] |
bind from multipart form-data |
Properties on these attributes include:
Name for query/header/cookie/form overridesIsRequired on all binding attributesIndex on [Path]Without an attribute:
CancellationToken is recognized speciallyStream, IFormFile, and IHttpFile are treated as streamed body valuesPOST and multipart behavior are inferred later from this metadata by the server and client packages.
IHttpFileRystem.Api also defines IHttpFile, a lightweight file abstraction used by the generated API pipeline.
Use it when you want an interface-level file type that is not tied directly to ASP.NET Core's IFormFile.
Registration currently uses typeof(T).GetMethods().
That means property getters are also exposed unless you remove them. The sample ITeamCalculator in src/Api/Test/Rystem.Api.Test.Domain/ITeamCalculator.cs would expose getter methods such as get_IsLive if left untouched.
If an interface contains overloaded methods, the builder keeps them unique by renaming later ones to _2, _3, and so on.
AddEndpointWithFactory<T>() records the intent to expand named factory endpoints, but the actual fan-out happens in Rystem.Api.Server during UseEndpointApi().
The client package does not currently perform the same automatic expansion from factory names.
src/Api/Test/Rystem.Api.Test.Domain/ServiceCollectionExtensions.cssrc/Api/Test/Rystem.Api.Test.Domain/IColam.cssrc/Api/Test/Rystem.Api.Test.Domain/ISalubry.cssrc/Api/Test/Rystem.Api.Test.Domain/ITeamCalculator.cssrc/Api/Test/Rystem.Api.Test.Domain/IEmbeddingService.csUse this package when you want to define the shared API contract once and let the server and client packages interpret it consistently.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 2 NuGet packages that depend on Rystem.Api:
| Package | Downloads |
|---|---|
|
Rystem.Api.Client
Rystem.Api helps you to integrate Api Server and Automated Client for Aspect-Oriented programming. |
|
|
Rystem.Api.Server
Rystem.Api helps you to integrate Api Server and Automated Client for Aspect-Oriented programming. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.8 | 5,613 | 5/13/2026 |
| 10.0.7 | 273 | 3/26/2026 |
| 10.0.6 | 433,538 | 3/3/2026 |
| 10.0.5 | 252 | 2/22/2026 |
| 10.0.4 | 254 | 2/9/2026 |
| 10.0.3 | 148,000 | 1/28/2026 |
| 10.0.1 | 209,123 | 11/12/2025 |
| 9.1.3 | 390 | 9/2/2025 |
| 9.1.2 | 764,522 | 5/29/2025 |
| 9.1.1 | 97,965 | 5/2/2025 |
| 9.0.32 | 186,677 | 4/15/2025 |
| 9.0.31 | 5,933 | 4/2/2025 |
| 9.0.30 | 88,910 | 3/26/2025 |
| 9.0.29 | 9,146 | 3/18/2025 |
| 9.0.28 | 325 | 3/17/2025 |
| 9.0.27 | 350 | 3/16/2025 |
| 9.0.26 | 371 | 3/13/2025 |
| 9.0.25 | 52,219 | 3/9/2025 |
| 9.0.23 | 313 | 3/9/2025 |
| 9.0.21 | 444 | 3/6/2025 |