RESTween.Server 1.6.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package RESTween.Server --version 1.6.2
                    
NuGet\Install-Package RESTween.Server -Version 1.6.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RESTween.Server" Version="1.6.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RESTween.Server" Version="1.6.2" />
                    
Directory.Packages.props
<PackageReference Include="RESTween.Server" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RESTween.Server --version 1.6.2
                    
#r "nuget: RESTween.Server, 1.6.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RESTween.Server@1.6.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RESTween.Server&version=1.6.2
                    
Install as a Cake Addin
#tool nuget:?package=RESTween.Server&version=1.6.2
                    
Install as a Cake Tool

RESTween.Server

RESTween.Server is a source-generator package that creates thin ASP.NET Core controllers from RESTween API interfaces.

It is built for applications that want one shared REST contract interface and two generated adapters:

  • RESTween on the client side builds HTTP requests from the interface.
  • RESTween.Server on the server side generates ASP.NET Core controllers from the same interface.

Your business logic stays in a handler class that implements the interface. The generated controller only translates ASP.NET Core HTTP calls into handler method calls.

What This Package Provides

  • A Roslyn source generator shipped as an analyzer.
  • [RestweenController] opt-in attribute generated into the consuming project.
  • ASP.NET Core controller generation for interfaces marked with [RestweenController].
  • Mapping from RESTween HTTP attributes to ASP.NET Core MVC attributes.
  • Parameter binding generation for route, query, body, and header values.
  • Handler-first server design: generated controllers inject the API interface and call the registered implementation.
  • A dependency on RESTween.Core, so shared RESTween attributes are available.

Install

dotnet add package RESTween.Server

The package contains the generator under analyzers/dotnet/cs, so it runs at compile time in the consuming project.

The consuming ASP.NET Core project must reference ASP.NET Core MVC, usually through:

<Project Sdk="Microsoft.NET.Sdk.Web">

or another setup that provides Microsoft.AspNetCore.Mvc.

Define a Shared Interface

using RESTween.Attributes;
using RESTween.Server;

[RestweenController]
public interface IUserApi
{
    [Get("/users/{id}")]
    Task<UserDto> GetUserAsync([Route] int id);

    [Post("/users")]
    Task<UserDto> CreateUserAsync([Body] CreateUserDto dto);
}

Only interfaces marked with [RestweenController] are used by the generator.

Methods without [Get], [Post], [Put], or [Delete] are ignored.

Implement the Handler

Write normal application code by implementing the same interface:

public sealed class UserApiHandler : IUserApi
{
    public Task<UserDto> GetUserAsync(int id)
    {
        // Load user from your database, service, or domain layer.
        throw new NotImplementedException();
    }

    public Task<UserDto> CreateUserAsync(CreateUserDto dto)
    {
        // Create user using your business logic.
        throw new NotImplementedException();
    }
}

Register the handler in DI:

builder.Services.AddScoped<IUserApi, UserApiHandler>();
builder.Services.AddControllers();

Map controllers:

app.MapControllers();

What Gets Generated

For the interface above, RESTween.Server generates a controller similar to:

[ApiController]
public sealed class UserApiController : ControllerBase
{
    private readonly IUserApi _handler;

    public UserApiController(IUserApi handler)
    {
        _handler = handler;
    }

    [HttpGet("/users/{id}")]
    public Task<UserDto> GetUserAsync([FromRoute(Name = "id")] int id)
        => _handler.GetUserAsync(id);

    [HttpPost("/users")]
    public Task<UserDto> CreateUserAsync([FromBody] CreateUserDto dto)
        => _handler.CreateUserAsync(dto);
}

The generated controller is intentionally thin. It should not contain business rules, persistence logic, validation policy, or mapping logic. Put that in the handler or your application layer.

Attribute Mapping

HTTP method attributes are converted to ASP.NET Core MVC attributes:

[Get("/path")]    -> [HttpGet("/path")]
[Post("/path")]   -> [HttpPost("/path")]
[Put("/path")]    -> [HttpPut("/path")]
[Delete("/path")] -> [HttpDelete("/path")]

Parameter attributes are converted to MVC binding attributes:

[Route]  -> [FromRoute]
[Query]  -> [FromQuery]
[Body]   -> [FromBody]
[Header] -> [FromHeader]

Explicit names are preserved:

[Get("/users/{userId}")]
Task<UserDto> GetUserAsync([Route("userId")] int id);

Generated parameter:

[FromRoute(Name = "userId")] int id

Implicit Binding Rules

If a parameter does not have an explicit RESTween binding attribute, the generator chooses a binding using these rules:

  • If the parameter name appears in the URL template as {name}, it becomes [FromRoute(Name = "name")].
  • If the parameter is a simple type, enum, string, Guid, DateTime, or nullable simple type, it becomes [FromQuery(Name = "name")].
  • If the method is [Post] or [Put] and the parameter is complex, it becomes [FromBody].
  • Otherwise, complex values become [FromQuery(Name = "name")].

This keeps simple server interfaces concise while still allowing explicit attributes for public contracts.

Controller Names

Controller names are derived from interface names:

IUserApi -> UserApiController
IOrders  -> OrdersController

The generated controller is emitted into the same namespace as the interface.

A common layout is:

MyApp.Contracts
  - references RESTween.Core
  - contains IUserApi and DTOs

MyApp.Client
  - references RESTween
  - uses AddApiClient<IUserApi>(...)

MyApp.Api
  - references RESTween.Server
  - implements UserApiHandler : IUserApi
  - registers AddScoped<IUserApi, UserApiHandler>()

This gives you one shared contract and avoids duplicating endpoint strings between client and server.

Limitations

The current generator focuses on controller generation for MVP server support:

  • It generates ASP.NET Core MVC controllers, not Minimal APIs.
  • It only processes interfaces marked with [RestweenController].
  • It only generates endpoints for methods with [Get], [Post], [Put], or [Delete].
  • It expects the consuming project to provide ASP.NET Core MVC references.
  • It does not implement business logic, validation, authorization, filters, or custom response wrapping.

Use normal ASP.NET Core features around the generated controllers for authorization, filters, middleware, OpenAPI, validation, and exception handling.

  • RESTween.Core: shared RESTween attributes and contract primitives.
  • RESTween: runtime HTTP client proxy package for calling RESTween interfaces.

Use RESTween.Server when your ASP.NET Core application should expose REST endpoints from the same interfaces used by RESTween clients.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.7.10 96 5/7/2026
1.7.9 88 5/7/2026
1.6.8 91 5/7/2026
1.6.7 96 5/6/2026
1.6.6 92 5/6/2026
1.6.5 94 5/3/2026
1.6.4 103 5/3/2026
1.6.3 96 4/30/2026
1.6.2 98 4/30/2026
1.6.1 92 4/30/2026