Ответ
UseRouting и UseEndpoints — это два отдельных, но тесно связанных middleware в конвейере обработки запроса ASP.NET Core. Они разделяют процесс маршрутизации на две фазы.
app.UseRouting() — это промежуточное ПО для сопоставления маршрутов (route matching).
- Оно вычисляет, какой контроллер и действие (или минимальный API endpoint) должны обработать входящий HTTP-запрос, на основе его пути и метода.
- Не выполняет конечную обработку запроса. Его задача — определить маршрут и прикрепить к контексту запроса (
HttpContext) метаданные (например, выбранныйEndpoint). - После
UseRoutingвы можете использовать middleware, которым нужна информация о маршруте (например,app.UseAuthorization()).
app.UseEndpoints() — это промежуточное ПО для выполнения конечной точки (endpoint execution).
- Оно принимает решение, сделанное
UseRouting, и вызывает соответствующий обработчик (метод контроллера, делегат минимального API, Razor Page и т.д.). - Внутри
UseEndpointsвы настраиваете сами конечные точки с помощью методовMapGet,MapControllers,MapRazorPages.
Типичная последовательность в Startup.Configure:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ... Другое middleware (например, для обработки ошибок, статических файлов)
app.UseRouting(); // Фаза 1: Сопоставление маршрута
app.UseAuthentication(); // Может использовать информацию о маршруте
app.UseAuthorization(); // Может использовать информацию о маршруте
app.UseEndpoints(endpoints => // Фаза 2: Выполнение конечной точки
{
endpoints.MapControllers(); // Регистрация маршрутов для контроллеров
endpoints.MapGet("/hello", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
}
Итог: UseRouting — «мы решили, куда идти», UseEndpoints — «мы пошли туда и выполнили код».
Ответ 18+ 🔞
Давай разжую эту тему про UseRouting и UseEndpoints, чтобы ты понял, как там под капотом всё ебётся.
Представь себе почтальона Печкина, который принёс тебе письмо. Так вот, UseRouting — это когда он смотрит на конверт и думает: «Ага, квартира 44, семья Сидоровых, тема — жалоба на шум». Он определил адресата, но письмо в руки не отдал. Просто приклеил на лоб записку «Сидоровым, прочитать».
А UseEndpoints — это уже сам момент, когда дверь открывается, Сидоровы берут конверт, вскрывают и начинают орать: «Опять эти соседи сверху с перфоратором!». Это и есть выполнение, сам вызов твоего кода.
Короче, по полочкам:
-
app.UseRouting()— СОПОСТАВЛЕНИЕ МАРШРУТА. Этот кусок кода — как умный сортировщик на почте. Он берёт входящий запрос (URL, метод), прогоняет его по всем зарегистрированным шаблонам (типа/api/users/{id}) и находит подходящий. Нашёл — и прикрепляет к запросу метку «Эй, следующий за мной, вот endpoint, который будет это обрабатывать». Сам он ничего не выполняет, только выбирает. Как будто говорит: «Окей, запрос на/api/users/5GET — это будет методGetUserByIdвUsersController». -
app.UseEndpoints()— ВЫПОЛНЕНИЕ КОНЕЧНОЙ ТОЧКИ. А вот это уже непосредственный вызов. Тот самый методGetUserById(5)запускается, лезет в базу, формирует ответ и отдаёт его. ВнутриUseEndpointsты как раз и говоришь, какие есть endpoint'ы: контроллеры, Razor Pages или вот эти минимальные API-делегаты.
Зачем их разделили, эти два этапа? А затем, что между «выбрать, кто будет обрабатывать» и «обработать» нужно иногда вставить какую-нибудь промежуточную хуйню. Например, авторизацию.
Смотри, классическая раскладка в Startup.Configure:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ... тут всякая общая хуета: обработка ошибок, статические файлы
app.UseRouting(); // Фаза 1: Печкин определил адрес (Сидоровы, кв.44)
// А вот теперь, ЗНАЯ, КУДА ИДЁТ ЗАПРОС, можно проверить пропуск.
app.UseAuthentication(); // Проверяет, кто там стучится (аутентификация)
app.UseAuthorization(); // Проверяет, а имеет ли право этот человек стучать именно в ЭТУ дверь (авторизация)
// Без UseRouting() эти штуки не знали бы, какие требования к доступу у endpoint'а Сидоровых.
app.UseEndpoints(endpoints => // Фаза 2: Вскрытие конверта и выполнение
{
endpoints.MapControllers(); // Все маршруты из контроллеров
endpoints.MapGet("/hello", async context => // Минимальный API
{
await context.Response.WriteAsync("Hello World!");
});
});
}
Итог, чтобы в голове отложилось:
UseRouting — «РЕШИЛИ, куда идти». Маршрутизатор.
UseEndpoints — «ПОШЛИ туда и СДЕЛАЛИ дело». Исполнитель.
Разделили для гибкости, чтобы между решением и действием можно было вставить логику, которой нужно знать — а к кому, собственно, запрос-то пришёл. Всё гениальное — просто, а когда непросто, то просто нужно знать, где что ебётся.