Scott Hanselman

Carter Community for ASP.NET Core means enjoyable Web APIs on the cutting edge

August 19, 2021 Comment on this post [4] Posted in ASP.NET | DotNetCore | Open Source
Sponsored By

I blogged about the open source Carter Community Project in 2019. Let's check in and see what's going on today in 2021!

With .NET 6 on the near horizon, one notes that Carter has a net6 branch. Per their website, this is the goal of the Carter framework:

Carter is framework that is a thin layer of extension methods and functionality over ASP.NET Core allowing code to be more explicit and most importantly more enjoyable.

As of today you can bring Carter into your .NET 6 projects like this:

dotnet add package Carter --version 6.0.0-pre2

And the .NET 6 samples are under active development! Let's bring it down with a clone, switch to the net6 branch and give it a go.

Here's as simple Web API sample with Carter that returns a list of actors at localhost:5001/actors

using Carter;
using CarterSample.Features.Actors;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;


var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IActorProvider, ActorProvider>();
builder.Services.AddCarter();

var app = builder.Build();

app.MapCarter();
app.Run();

Nice! This is using new .NET 6 features so there's no Main(), it's implied. The builder has an ActorProvider added as a Singleton. I bet we'll use that when we ask for /actors in our browser or favorite HTTP API client.

public class ActorsModule : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
app.MapGet("/actors", (IActorProvider actorProvider, HttpResponse res) =>
{
var people = actorProvider.Get();
return people;
});
...
}
}

This is nice and clean. Everything is using Dependency Injection so no one is "newing up" an Actor. You'll note also that returning the Actors as JSON is implied when we return the IEmumerable<Actor> that comes from actorProvider.Get().

In fact, the whole Actor Module is just 80 lines so I'll include it here:

public class ActorsModule : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
app.MapGet("/actors", (IActorProvider actorProvider, HttpResponse res) =>
{
var people = actorProvider.Get();
return people;
});

app.MapGet("/actors/{id:int}", (int id, IActorProvider actorProvider, HttpResponse res) =>
{
var person = actorProvider.Get(id);
return res.Negotiate(person);
});

app.MapPut("/actors/{id:int}", async (HttpRequest req, Actor actor, HttpResponse res) =>
{
var result = req.Validate<Actor>(actor);

if (!result.IsValid)
{
res.StatusCode = 422;
await res.Negotiate(result.GetFormattedErrors());
return;
}

//Update the user in your database

res.StatusCode = 204;
});

app.MapPost("/actors", async (HttpContext ctx, Actor actor) =>
{
var result = ctx.Request.Validate<Actor>(actor);

if (!result.IsValid)
{
ctx.Response.StatusCode = 422;
await ctx.Response.Negotiate(result.GetFormattedErrors());
return;
}

//Save the user in your database

ctx.Response.StatusCode = 201;
await ctx.Response.Negotiate(actor);
});

app.MapDelete("/actors/{id:int}", (int id, IActorProvider actorProvider, HttpResponse res) =>
{
actorProvider.Delete(id);
return Results.StatusCode(204);
});

app.MapGet("/actors/download", async (HttpResponse response) =>
{
using (var video = new FileStream("earth.mp4", FileMode.Open)) //24406813
{
await response.FromStream(video, "video/mp4");
}
});

app.MapGet("/empty", () => Task.CompletedTask);

app.MapGet("/actors/sample", () => Task.CompletedTask);

app.MapPost("/actors/sample", () => Task.CompletedTask);

app.MapGet("/nullable", () => Task.CompletedTask);
}
}

Note the API example at /actors/download that shows how to return a file like an MP4. Nice and simple. This sample also includes thoughtful validation code with FluentValidation extension methods like ctx.Request.Validate().

Carter is opinionated but surprisingly flexible. You can use two different routing APIs, or clean and performant Endpoint routing:

this.Get("/", (req, res) => res.WriteAsync("There's no place like 127.0.0.1")).RequireAuthorization();

It even supports OpenAPI out of the box! Carter has an active Slack as well as Templates you can add to make your next File | New Project easier!

dotnet new -i CarterTemplate
The following template packages will be installed:
CarterTemplate

Success: CarterTemplate::5.2.0 installed the following templates:
Template Name Short Name Language Tags
--------------- ---------- -------- ------------------------------
Carter Template carter [C#] Carter/Carter Template/NancyFX

There's a lot of great innovation happening in the .NET open source space right now.

Carter Source Code

Carter is just one cool example. Go check out Carter on GitHub, give them a Star, try it out and get involved in open source!


Sponsor: YugabyteDB is a distributed SQL database designed for resilience and scale. It is 100% open source, PostgreSQL-compatible, enterprise-grade, and runs across all clouds. Sign up and get a free t-shirt

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
August 22, 2021 17:43
i love ASP.NET, thanks for this usefull article. please be more active
August 22, 2021 18:40
This looks really nice, was ogling abp.io but wasn’t sure I wanted to go “all in”, this might be the middle ground.

After decades of this stuff, I would absolutely devour a discussion of “what aspnetcore framework/platform offers the fastest path to db->business->pages so I can actually think about adding objects & content instead of all the fiddly bits that occupy 80% of my effort”.. Does that exist? In the murky mists of time it was called Rad and occasionally it was brilliant.
August 23, 2021 17:11
There has been some talk about retiring Carter in leu of the upcoming Minimal API Hosting feature. I really like and use Carter and would be sad to see it go. It's worth checking out this twitter thread for more information.
August 24, 2021 12:04
Hey, found it was very interesting and useful.


Thanks
MEDIASHAREiQ Team
https://www.mediashareiq.com/

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.