Lebedeff.MicroEndpoints 2.0.2

Suggested Alternatives

Lebedeff.MicroEndpoints 3.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Lebedeff.MicroEndpoints --version 2.0.2                
NuGet\Install-Package Lebedeff.MicroEndpoints -Version 2.0.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="Lebedeff.MicroEndpoints" Version="2.0.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Lebedeff.MicroEndpoints --version 2.0.2                
#r "nuget: Lebedeff.MicroEndpoints, 2.0.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.
// Install Lebedeff.MicroEndpoints as a Cake Addin
#addin nuget:?package=Lebedeff.MicroEndpoints&version=2.0.2

// Install Lebedeff.MicroEndpoints as a Cake Tool
#tool nuget:?package=Lebedeff.MicroEndpoints&version=2.0.2                

publish to nuget MicroEndpoints on NuGet NuGet License

MicroEndpoints

MicroEndpoints is a .NET library that simplifies creating HTTP endpoints in a minimalistic and clean manner. It's designed to work with .NET 8's Minimal APIs.

Minimal APIs in .NET 8 offer an easy way to build HTTP APIs with the flexibility to add more features as your project grows. They are great for creating HTTP APIs where you typically send and receive HTTP requests and responses. These APIs are often used with single-page apps, mobile clients, and for public HTTP APIs.

Here are a few benefits of Minimal APIs:

  • Simplicity: With Minimal APIs, you can use a single line of code to express an API endpoint, making it easy to understand.
  • Productivity: Minimal APIs require less code and less ceremony, which leads to a productivity gain.
  • Performance: Minimal APIs are built on top of the same high-performance components as the rest of ASP.NET Core.

For more detailed information, please refer to the Microsoft Documentation on Minimal APIs.

With MicroEndpoints, you can leverage the simplicity and performance of Minimal APIs with a structured and easy-to-use model, making your development process even more efficient.

Getting Started

To install the library, you can use the .NET CLI:

dotnet add package Lebedeff.MicroEndpoints

After installing the package, make sure to include the following line in your Program.cs:

//...
builder.Services.AddMicroEndpoints(Assembly.GetAssembly(typeof(Program)));
//...
var app = builder.Build();
//...
app.UseMicroEndpoints();

app.Run();

Endpoint Types

MicroEndpoints provides the flexibility to create synchronous or asynchronous endpoints based on your application's needs.

Synchronous Endpoints

If you don't have any I/O-bound work that would benefit from asynchrony, you can create synchronous endpoints. Here's an example:

public class MySyncEndpoint : EndpointBaseSync
    .WithRequest<MyRequest>
    .WithIResult
{
  public override IResult Handle(MyRequest request)
  {
    // Implementation...
  }
}

In the example above, MySyncEndpoint is a synchronous endpoint that handles a MyRequest request and returns an IResult.

Asynchronous Endpoints

If you're performing I/O-bound operations, such as network requests or database queries, you should use asynchronous endpoints. Here's an example:

public class MyAsyncEndpoint : EndpointBaseAsync
    .WithRequest<MyRequest>
    .WithIResult
{
  public override async Task<IResult> HandleAsync(MyRequest request, CancellationToken cancellationToken = default)
  {
    // Implementation...
  }
}

In this example, MyAsyncEndpoint is an asynchronous endpoint that handles a MyRequest request and returns an IResult.

Endpoint Results

The result of an endpoint can be of any type. However, it's recommended to use IResult for its flexibility and expressiveness. IResult allows you to easily produce different HTTP responses.

public class MyEndpoint : EndpointBaseAsync
    .WithoutRequest
    .WithIResult
{
  [Get("api/authors")]
  public override async Task<IResult> HandleAsync(CancellationToken cancellationToken = default)
  {
    // Implementation...
    return Ok();
  }
}

If you want to return a custom type, you can do so by specifying the type when inheriting from EndpointBaseAsync or EndpointBaseSync. Here's an example:

public class MyEndpoint : EndpointBaseAsync
    .WithRequest<MyRequest>
    .WithResult<MyResponse> // MyResponse is a custom class
{
  public override async Task<MyResponse> HandleAsync(MyRequest request, CancellationToken cancellationToken = default)
  {
    // Implementation...
  }
}

In the example above, MyEndpoint is an asynchronous endpoint that handles a MyRequest request and returns a MyResponse result.

Dependency Injection

If you need to use services from the dependency injection (DI) container in your endpoints, you can do so within the Handle or HandleAsync methods.

You can use the GetService method from the IServiceProvider to retrieve your services. Here's an example:

public override async Task<IResult> HandleAsync([FromServices] IServiceProvider serviceProvider, MyRequest request, CancellationToken cancellationToken = default)
{
  // Get services from the DI container
  _repository = serviceProvider.GetService<IAsyncRepository<Author>>()!;
  _mapper = serviceProvider.GetService<IMapper>()!;

  // Implementation...
}

In the example above, IAsyncRepository<Author> and IMapper are being retrieved from the service provider, which is injected into the method by the framework.

Remember to add a reference to the Microsoft.Extensions.DependencyInjection namespace to use the GetService method.

How to Use

MicroEndpoints provides a base class EndpointBaseAsync that you can inherit from to define your own endpoints. Here's how you can use it:

public class Get : EndpointBaseAsync
      .WithRequest<int>
      .WithIResult
{
  //...
}

In this example, the Get class is an endpoint that expects a request with an integer parameter and returns an IResult type. The actual handling of the request is done in the HandleAsync method which needs to be overridden.

Examples

Here are some examples:

Get Endpoint

public class Get : EndpointBaseAsync
      .WithRequest<int>
      .WithIResult
{
  private IAsyncRepository<Author> _repository;
  private IMapper _mapper;

  public Get(IAsyncRepository<Author> repository, IMapper mapper)
  {
    _repository = repository;
    _mapper = mapper;
  }

  [Get("api/authors/{id}")]
  public override async Task<IResult> HandleAsync([FromServices] IServiceProvider serviceProvider, int id, CancellationToken cancellationToken = default)
  {
    // Implementation...
  }
}

Post Endpoint

public class Create : EndpointBaseAsync
    .WithRequest<CreateAuthorCommand>
    .WithIResult
{
  private IAsyncRepository<Author> _repository;
  private IMapper _mapper;

  public Create(IAsyncRepository<Author> repository, IMapper mapper)
  {
    _repository = repository;
    _mapper = mapper;
  }

  [Post("api/authors")]
  public override async Task<IResult> HandleAsync([FromServices] IServiceProvider serviceProvider, [FromBody] CreateAuthorCommand request, CancellationToken cancellationToken = default)
  {
    // Implementation...
  }
}

Put Endpoint

public class Create : EndpointBaseAsync
    .WithRequest<CreateAuthorCommand>
    .WithIResult
{
  private IAsyncRepository<Author> _repository;
  private IMapper _mapper;

  public Create(IAsyncRepository<Author> repository, IMapper mapper)
  {
    _repository = repository;
    _mapper = mapper;
  }

  [Put("api/authors")]
  public override async Task<IResult> HandleAsync([FromServices] IServiceProvider serviceProvider, [FromBody] CreateAuthorCommand request, CancellationToken cancellationToken = default)
  {
    // Implementation...
  }
}

Delete Endpoint

public class Delete : EndpointBaseAsync
    .WithRequest<int>
    .WithIResult
{
  private IAsyncRepository<Author> _repository;

  public Delete(IAsyncRepository<Author> repository)
  {
    _repository = repository;
  }

  [Delete("api/authors/{id:int}")]
  public override async Task<IResult> HandleAsync([FromServices] IServiceProvider serviceProvider, [FromRoute] int id, CancellationToken cancellationToken = default)
  {
    // Implementation...
  }
}

You can see more examples in the examples directory.

Acknowledgements

We would like to express our gratitude towards Ardalis (Steve Smith) for creating the Ardalis.Endpoints package. His work served as an inspiration and provided a solid foundation for the development of MicroEndpoints.

We highly recommend checking out his package and other contributions to the .NET community.

Contributing

We welcome contributions! Please see CONTRIBUTING.md for details.

License

This project is licensed under the terms of the MIT license. See the LICENSE file.

Author

https://github.com/ShadyNagy

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Initial release.