Share via


En Düşük API uygulamalarında İşleyicileri Yönlendirme

Yapılandırılmış WebApplication bir , veya Deletegibi GetPostPut Pascal büyük/küçük harfli bir HTTP yöntemini destekler Map{Verb} ve MapMethods buradadır:{Verb}

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "This is a GET");
app.MapPost("/", () => "This is a POST");
app.MapPut("/", () => "This is a PUT");
app.MapDelete("/", () => "This is a DELETE");

app.MapMethods("/options-or-head", new[] { "OPTIONS", "HEAD" }, 
                          () => "This is an options or head request ");

app.Run();

Delegate Bu yöntemlere geçirilen bağımsız değişkenler "yol işleyicileri" olarak adlandırılır.

Yol işleyicileri

Yol işleyicileri, yol eşleştiğinde yürütülen yöntemlerdir. Yol işleyicileri bir lambda ifadesi, yerel bir işlev, örnek yöntemi veya statik bir yöntem olabilir. Yol işleyicileri zaman uyumlu veya zaman uyumsuz olabilir.

Lambda ifadesi

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/inline", () => "This is an inline lambda");

var handler = () => "This is a lambda variable";

app.MapGet("/", handler);

app.Run();

Yerel işlev

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

string LocalFunction() => "This is local function";

app.MapGet("/", LocalFunction);

app.Run();

Örnek yöntemi

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

var handler = new HelloHandler();

app.MapGet("/", handler.Hello);

app.Run();

class HelloHandler
{
    public string Hello()
    {
        return "Hello Instance method";
    }
}

Statik yöntem

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", HelloHandler.Hello);

app.Run();

class HelloHandler
{
    public static string Hello()
    {
        return "Hello static method";
    }
}

Uç noktanın dışında tanımlanmış Program.cs

En az API'nin içinde Program.csbulunması gerekmez.

Program.cs

using MinAPISeparateFile;

var builder = WebApplication.CreateSlimBuilder(args);

var app = builder.Build();

TodoEndpoints.Map(app);

app.Run();

TodoEndpoints.cs

namespace MinAPISeparateFile;

public static class TodoEndpoints
{
    public static void Map(WebApplication app)
    {
        app.MapGet("/", async context =>
        {
            // Get all todo items
            await context.Response.WriteAsJsonAsync(new { Message = "All todo items" });
        });

        app.MapGet("/{id}", async context =>
        {
            // Get one todo item
            await context.Response.WriteAsJsonAsync(new { Message = "One todo item" });
        });
    }
}

Ayrıca bu makalenin devamında Grupları yönlendirme bölümüne bakın.

Uç noktaya URL'ler oluşturmak için uç noktalara adlar verilebilir. Adlandırılmış uç nokta kullanmak, bir uygulamada yolları sabit kodlamaktan kaçınıyor:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/hello", () => "Hello named route")
   .WithName("hi");

app.MapGet("/", (LinkGenerator linker) => 
        $"The link to the hello route is {linker.GetPathByName("hi", values: null)}");

app.Run();

Yukarıdaki kod uç noktadan görüntülenir The link to the hello endpoint is /hello/ .

NOT: Uç nokta adları büyük/küçük harfe duyarlıdır.

Uç nokta adları:

  • Genel olarak benzersiz olması gerekir.
  • OpenAPI desteği etkinleştirildiğinde OpenAPI işlem kimliği olarak kullanılır. Daha fazla bilgi için bkz . OpenAPI.

Rota Parametreleri

Yol parametreleri, yol deseni tanımının bir parçası olarak yakalanabilir:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/users/{userId}/books/{bookId}", 
    (int userId, int bookId) => $"The user id is {userId} and book id is {bookId}");

app.Run();

Yukarıdaki kod URI'sinden /users/3/books/7döndürürThe user id is 3 and book id is 7.

Yol işleyicisi, yakalanacak parametreleri bildirebilir. Yakalamak üzere bildirilen parametrelerle bir yola istek yapıldığında, parametreler ayrıştırılır ve işleyiciye geçirilir. Bu, değerleri güvenli bir şekilde tür olarak yakalamayı kolaylaştırır. Önceki kodda userId ve bookId her ikisi de intşeklindedir.

Yukarıdaki kodda, herhangi bir yol değeri bir int'a dönüştürülemezse bir özel durum oluşturulur. GET isteği /users/hello/books/3 aşağıdaki özel durumu oluşturur:

BadHttpRequestException: Failed to bind parameter "int userId" from "hello".

Joker karakter ve tüm yolları yakalama

Aşağıdaki catch all route returns Routing to hello from the '/posts/hello' endpoint:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/posts/{*rest}", (string rest) => $"Routing to {rest}");

app.Run();

Yol kısıtlamaları

Yol kısıtlamaları, bir yolun eşleşen davranışını kısıtlar.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

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}");

app.Run();

Aşağıdaki tabloda, önceki yol şablonları ve bunların davranışları gösterilmektedir:

Rota Şablonu Örnek Eşleşen URI
/todos/{id:int} /todos/1
/todos/{text} /todos/something
/posts/{slug:regex(^[a-z0-9_-]+$)} /posts/mypost

Daha fazla bilgi için bkz. ASP.NET Core'da Yönlendirme bölümünde yönlendirme kısıtlaması başvurusu.

Yol grupları

Uzantı yöntemi, MapGroup ortak bir ön eke sahip uç nokta gruplarını düzenlemeye yardımcı olur. Yinelenen kodu azaltır ve uç nokta meta verilerini ekleyen ve WithMetadata gibi RequireAuthorization yöntemlere tek bir çağrıyla tüm uç nokta gruplarını özelleştirmeye olanak tanır.

Örneğin, aşağıdaki kod iki benzer uç nokta grubu oluşturur:

app.MapGroup("/public/todos")
    .MapTodosApi()
    .WithTags("Public");

app.MapGroup("/private/todos")
    .MapTodosApi()
    .WithTags("Private")
    .AddEndpointFilterFactory(QueryPrivateTodos)
    .RequireAuthorization();


EndpointFilterDelegate QueryPrivateTodos(EndpointFilterFactoryContext factoryContext, EndpointFilterDelegate next)
{
    var dbContextIndex = -1;

    foreach (var argument in factoryContext.MethodInfo.GetParameters())
    {
        if (argument.ParameterType == typeof(TodoDb))
        {
            dbContextIndex = argument.Position;
            break;
        }
    }

    // Skip filter if the method doesn't have a TodoDb parameter.
    if (dbContextIndex < 0)
    {
        return next;
    }

    return async invocationContext =>
    {
        var dbContext = invocationContext.GetArgument<TodoDb>(dbContextIndex);
        dbContext.IsPrivate = true;

        try
        {
            return await next(invocationContext);
        }
        finally
        {
            // This should only be relevant if you're pooling or otherwise reusing the DbContext instance.
            dbContext.IsPrivate = false;
        }
    };
}
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group)
{
    group.MapGet("/", GetAllTodos);
    group.MapGet("/{id}", GetTodo);
    group.MapPost("/", CreateTodo);
    group.MapPut("/{id}", UpdateTodo);
    group.MapDelete("/{id}", DeleteTodo);

    return group;
}

Bu senaryoda, sonuçta üst bilgi 201 Created için Location göreli bir adres kullanabilirsiniz:

public static async Task<Created<Todo>> CreateTodo(Todo todo, TodoDb database)
{
    await database.AddAsync(todo);
    await database.SaveChangesAsync();

    return TypedResults.Created($"{todo.Id}", todo);
}

İlk uç nokta grubu yalnızca ön ekli /public/todos isteklerle eşleşir ve kimlik doğrulaması olmadan erişilebilir. İkinci uç nokta grubu yalnızca ön ekli isteklerle /private/todos eşleşir ve kimlik doğrulaması gerektirir.

QueryPrivateTodosUç nokta filtresi fabrikası, özel todo verilerine erişmeye ve bunları depolamaya izin vermek için yol işleyicisinin TodoDb parametrelerini değiştiren yerel bir işlevdir.

Yol grupları, yol parametreleri ve kısıtlamalarıyla iç içe grupları ve karmaşık ön ek desenlerini de destekler. Aşağıdaki örnekte, gruba eşlenen user ve yol işleyicisi dış grup ön eklerinde tanımlanan ve {group} yol parametrelerini yakalayabilir{org}.

Ön ek de boş olabilir. Bu, yol desenini değiştirmeden bir uç nokta grubuna uç nokta meta verileri veya filtreleri eklemek için yararlı olabilir.

var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");

Bir gruba filtre veya meta veri eklemek, bir iç gruba veya belirli bir uç noktaya eklenmiş olabilecek ek filtreler veya meta veriler eklemeden önce bunları her uç noktaya tek tek eklemekle aynı şekilde davranır.

var outer = app.MapGroup("/outer");
var inner = outer.MapGroup("/inner");

inner.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/inner group filter");
    return next(context);
});

outer.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/outer group filter");
    return next(context);
});

inner.MapGet("/", () => "Hi!").AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("MapGet filter");
    return next(context);
});

Yukarıdaki örnekte dış filtre, ikinci kez eklenmiş olsa bile gelen isteği iç filtreden önce günlüğe kaydeder. Filtreler farklı gruplara uygulandığından, birbirlerine göre eklendikleri sıra önemli değildir. Sipariş filtrelerinin eklenmesi, aynı gruba veya belirli bir uç noktaya uygulandığında önemlidir.

için bir istek /outer/inner/ aşağıdakileri günlüğe kaydeder:

/outer group filter
/inner group filter
MapGet filter

Parametre bağlama

Minimum API uygulamalarında parametre bağlama, yol işleyicisi parametrelerinin nasıl dolduruldığıyla ilgili kuralları ayrıntılı olarak açıklar.

Yanıtlar

Minimal API uygulamalarında yanıt oluşturma, yol işleyicilerinden döndürülen değerlerin yanıtlara nasıl dönüştürüldüğünü ayrıntılı olarak açıklar.