Minimal APIs at a glance in .NET 6
source link: https://www.hanselman.com/blog/minimal-apis-at-a-glance-in-net-6
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Minimal APIs at a glance in .NET 6
David has been quietly creating an amazing piece of documentation for Minimal APIs in .NET 6. At some point when it's released we'll work with David to get everything promoted to formal documentation, but as far as I'm concerned if he is slapping the keyboard anywhere and it shows up anywhere with a URL then I'm happy with the result!
Let's explore a bit here and I encourage you to head over to the main Gist here.
To start, we see how easy it is to make a .NET 6 (minimal) app to say Hello World over HTTP on localhost:5000/5001
var app = WebApplication.Create(args);
app.MapGet(
"/"
, () =>
"Hello World"
);
app.Run();
Lovely. It's basically nothing. Can I do more HTTP Verbs? Yes.
app.MapGet(
"/"
, () =>
"This is a GET"
);
app.MapPost(
"/"
, () =>
"This is a POST"
);
app.MapPut(
"/"
, () =>
"This is a PUT"
);
app.MapDelete(
"/"
, () =>
"This is a DELETE"
);
What about other verbs? More than one?
app.MapMethods(
"/options-or-head"
,
new
[] {
"OPTIONS"
,
"HEAD"
}, () =>
"This is an options or head request "
);
Lambda expressions, not objects, are our "atoms" that we build molecules with in this world. They are the building blocks.
app.MapGet(
"/"
, () =>
"This is an inline lambda"
);
var handler = () =>
"This is a lambda variable"
;
app.MapGet(
"/"
, handler)
But it's just a function, so you can organize things however you want!
var handler =
new
HelloHandler();
app.MapGet(
"/"
, handler.Hello);
class
HelloHandler
{
public
string
Hello()
{
return
"Hello World"
;
}
}
You can capture route parameters as part of the route pattern definition.
app.MapGet(
"/users/{userId}/books/{bookId}"
, (
int
userId,
int
bookId) => $
"The user id is {userId} and book id is {bookId}"
);
Route constraints are influence the matching behavior of a route. See how this is in order of specificity:
app.MapGet(
"/todos/{id:int}"
, (
int
id) => db.Todos.Find(id));
app.MapGet(
"/todos/{text}"
, (
string
text) => db.Todos.Where(t => t.Text.Contains(text));
app.MapGet(
"/posts/{slug:regex(^[a-z0-9_-]+$)}"
, (
string
slug) => $
"Post {slug}"
);
Attributes can be used to explicitly declare where parameters should be bound from! So you can pick and choose from all over!
using
Microsoft.AspNetCore.Mvc;
app.MapGet(
"/{id}"
, ([FromRoute]
int
id,
[FromQuery(Name =
"p"
)]
int
page,
[FromServices]Service service,
[FromHeader(Name =
"Content-Type"
)]
string
contentType) => { });
I can customize the response:
app.MapGet(
"/todos/{id}"
, (
int
id, TodoDb db) =>
db.Todos.Find(id)
is
Todo todo
? Results.Ok(todo)
: Results.NotFound()
);
Here's a cool example of taking a file upload and writing it to a local file. Nice and clean.
app.MapGet(
"/upload"
, async (HttpRequest req) =>
{
if
(!req.HasFormContentType)
{
return
Results.BadRequest();
}
var form = await req.ReadFormAsync();
var file = form.Files[
"file"
];
if
(file
is
null
)
{
return
Results.BadRequest();
}
var uploads = Path.Combine(uploadsPath, file.FileName);
await
using
var fileStream = File.OpenWrite(uploads);
await
using
var uploadStream = file.OpenReadStream();
await uploadStream.CopyToAsync(fileStream);
return
Results.NoContent();
})
.Accepts<IFormFile>(
"multipart/form-data"
);
Go check out this great (and growing) online resource to learn about .NET 6 minimal APIs.
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.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK