.NET 8 中的 Mini WebApi

介绍

    .NET 8 中的极简 API 隆重登场,重新定义了我们构建 Web 服务的方式。如果您想知道极简 API 的工作原理以及它们如何简化您的开发流程,让我们通过一些引人入胜的示例来深入了解一下。

.NET 极简主义的诞生

    想想我们曾经不得不为一个简单的 Web 服务编写几页代码。很乏味,对吧?最小 API 就像一股清新的空气。它们在 .NET 6 中引入,并在 .NET 8 中得到改进,消除了传统 ASP.NET Core MVC 模型的复杂性。不再需要控制器,不需要广泛的配置 — 这正是您所需要的。

为什么要使用最少的 API?

    1、效率:少写,多做。这是现代开发人员的口头禅。

    2、性能:它们精简、高效、快速,非常适合高性能场景。

    3、易于使用:.NET 新手?没问题!最少的 API 易于访问和掌握。

    4、灵活性:简单并不意味着受限。从微服务到大型应用程序,它们都能满足您的需求。

入门

    要开始这一旅程,请确保您已安装.NET 8 SDK。打开您最喜欢的代码编辑器,让我们创建我们的第一个最小 API。

重要设置信息:在运行本文提供的示例之前,请确保您已安装必要的 NuGet 包。对于涉及 OpenAPI 文档的功能,您将需要该Microsoft.AspNetCore.OpenApi包。您可以使用以下命令通过 NuGet 包管理器控制台安装它:

Install-Package Microsoft.AspNetCore.OpenApi

此包对于使用以下示例中显示的扩展方法至关重要WithOpenApi。

示例 1:你好,世界!

    经典入门。此 API 返回友好问候语。运行此 API,瞧!您的 API 将在http://localhost:<port>/向全世界问好。请注意,端口号可能会根据您的设置而变化。
    
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

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

app.MapGet("/", () => "Hello, World!");

app.Run();
Response body:
Hello, World!
Response headers:
content-type: text/plain; charset=utf-8 
date: Tue,21 Nov 2023 13:38:37 GMT 
server: Kestrel 

设置舞台:图书服务

    在进入路由之前,让我们先了解一下设置。我们定义了一个IBookService接口及其实现BookService,它模拟了一个图书数据库。这是将数据访问逻辑封装在服务层中的经典示例,它促进了关注点分离并使代码更易于维护。

背景介绍

    “想象一下,走进一个井然有序的数字图书馆,只需点击一下鼠标即可找到每本书。这就是我们BookService在 Minimal API 设置中创建的内容。这项服务是我们应用程序的支柱,用于管理和提供图书数据。”

namespace MinimalApis
{
    public interface IBookService
    {
        List<Book> GetBooks();
        
        Book GetBook(int id);
    }

    public class BookService : IBookService
    {
        private readonly List<Book> _books;

        public BookService()
        {
            _books = new List<Book>
            {
                new()
                {
                    Id = 1,
                    Title = "Dependency Injection in .NET",
                    Author = "Mark Seemann"
                },
                new()
                {
                    Id = 2,
                    Title = "C# in Depth",
                    Author = "Jon Skeet"
                },
                new()
                {
                    Id = 3,
                    Title = "Programming Entity Framework",
                    Author = "Julia Lerman"
                },
                new()
                {
                    Id = 4,
                    Title = "Programming WCF Services",
                    Author = "Juval Lowy and Michael Montgomery"
                }
            };
        }

        public List<Book> GetBooks()
        {
            return this._books;
        }

        public Book GetBook(int id)
        {
            var book = this._books.FirstOrDefault(x => x.Id == id);

            return book;
        }
    }

    public class Book
    {
        public int Id { get; set; }

        public string Title { get; set; }

        public string Author { get; set; }
    }
}

        这IBookService是我们的蓝图,声明了我们的服务必须提供哪些功能——列出所有书籍并通过 ID 获取特定的书籍。BookService是具体的实现,我们定义这些功能如何工作。

        在里面BookService,我们有一个私有列表_books,用作我们的模拟数据库。它预先填充了一些要模拟的书籍。这种设置让我们可以专注于 API 功能,而不必担心实际的数据库连接。

        该GetBooks方法返回所有书籍,同时GetBook使用 LINQ 通过其 ID 搜索书籍。这是一种处理数据的简单而强大的方法。

builder.Services.AddSingleton<IBookService, BookService>();

        最后,我们BookService通过依赖注入系统注册,将我们的 API 集成到 Minimal API 管道中。这样,它就可以BookService在我们的应用程序中的任何地方使用。

示例 2:获取所有书籍

    本示例演示如何列出图书馆中的所有书籍。

app.MapGet("/books", (IBookService bookService) => 
    TypedResults.Ok(bookService.GetBooks()))
    .WithName("GetBooks")
    .WithOpenApi(x => new OpenApiOperation(x)
    {
        Summary = "Get Library Books",
        Description = "Returns information about all the available books from the Amy's library.",
        Tags = new List<OpenApiTag> { new() { Name = "Amy's Library" } }
    });
    
端点定义:app.MapGet("/books", ...)此行在 URL 处定义一个 GET 端点/books。

依赖注入:(IBookService bookService)这里IBookService自动注入,允许访问图书服务。

服务交互:bookService.GetBooks()调用GetBooks的方法BookService来获取所有书籍。

响应:TypedResults.Ok(...)将书籍列表包装在 HTTP 200 OK 响应中。

Swagger文档:

.WithName("GetBooks"):为清楚起见,为端点分配一个名称。
.WithOpenApi(...):添加 Swagger UI 的描述信息,增强 API 文档。

在 Postman 或浏览器中,发送 GET 请求以https://localhost:<port>/books接收所有书籍的 JSON 列表。

[
  {
    "id": 1,
    "title": "Dependency Injection in .NET",
    "author": "Mark Seemann"
  },
  {
    "id": 2,
    "title": "C# in Depth",
    "author": "Jon Skeet"
  },
  {
    "id": 3,
    "title": "Programming Entity Framework",
    "author": "Julia Lerman"
  },
  {
    "id": 4,
    "title": "Programming WCF Services",
    "author": "Juval Lowy and Michael Montgomery"
  }
]

示例 3:通过 ID 获取特定书籍
此示例显示如何通过 ID 检索特定书籍。

app.MapGet("/books/{id}", Results<Ok<Book>, NotFound> (IBookService bookService, int id) =>
        bookService.GetBook(id) is { } book 
            ? TypedResults.Ok(book) 
            : TypedResults.NotFound()
    )
    .WithName("GetBookById")
    .WithOpenApi(x => new OpenApiOperation(x)
    {
        Summary = "Get Library Book By Id",
        Description = "Returns information about selected book from the Amy's library.",
        Tags = new List<OpenApiTag> { new() { Name = "Amy's Library" } }
    });
    
端点定义:app.MapGet("/books/{id}", ...)在 处定义一个 GET 端点/books/{id},其中{id}是表示书籍 ID 的变量。

路线逻辑:bookService.GetBook(id) is { } book尝试通过 ID 查找书籍。如果找到,book则不为空。

条件响应:

如果找到:TypedResults.Ok(book)返回状态为 OK 的书籍。
如果未找到:TypedResults.NotFound()返回 404 未找到状态。
Swagger 文档:与示例 2 类似,为 Swagger UI 提供有意义的信息。

        要查找 ID 为 3 的图书,请向 发送 GET 请求https://localhost:<port>/books/3。您将获得 JSON 格式的图书详细信息,如果 ID 不存在,则收到 404 Not Found 响应。

{
  "id": 3,
  "title": "Programming Entity Framework",
  "author": "Julia Lerman"
}

深入了解完整代码:完整的 Program.cs

        在本节中,让我们探索一下该Program.cs文件。这是我们的 Minimal API 的所有部分汇集在一起​​的地方,从设置服务到定义端点。我将带您了解整个代码,将其分解为易于理解的部分,以便更清楚地理解。

完整代码清单

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.OpenApi.Models;
using MinimalApis;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<IBookService, BookService>();

var app = builder.Build();

// configure exception middleware
app.UseStatusCodePages(async statusCodeContext
    => await Results.Problem(statusCode: statusCodeContext.HttpContext.Response.StatusCode)
        .ExecuteAsync(statusCodeContext.HttpContext));

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();


// example 1
app.MapGet("/", () => "Hello, World!");

// example 2
app.MapGet("/books", (IBookService bookService) => 
    TypedResults.Ok(bookService.GetBooks()))
.WithName("GetBooks")
.WithOpenApi(x => new OpenApiOperation(x)
{
    Summary = "Get Library Books",
    Description = "Returns information about all the available books from the Amy's library.",
    Tags = new List<OpenApiTag> { new() { Name = "Amy's Library" } }
});

// example 3
app.MapGet("/books/{id}", Results<Ok<Book>, NotFound> (IBookService bookService, int id) =>
        bookService.GetBook(id) is { } book 
            ? TypedResults.Ok(book) 
            : TypedResults.NotFound()
    )
    .WithName("GetBookById")
    .WithOpenApi(x => new OpenApiOperation(x)
    {
        Summary = "Get Library Book By Id",
        Description = "Returns information about selected book from the Amy's library.",
        Tags = new List<OpenApiTag> { new() { Name = "Amy's Library" } }
    });

app.Run();

设置服务

    在这里,我们启动应用程序并将其注入BookService到我们的服务集合中。这可BookService在整个应用程序中使用。此外,我们还为 API 文档设置了 Swagger。

var builder = WebApplication.CreateBuilder(args); 
builder.Services.AddSingleton<IBookService, BookService>(); 
builder.Services.AddEndpointsApiExplorer(); 
builder.Services.AddSwaggerGen();

配置中间件

    本部分主要介绍中间件配置。UseStatusCodePages有助于处理 HTTP 状态代码,同时UseHttpsRedirection确保安全连接。在开发环境中启用 Swagger UI,以便于测试和探索。

var app = builder.Build();
app.UseStatusCodePages(...);
app.UseHttpsRedirection();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

定义端点

    这里,我们定义了三个端点:一个简单的问候语,一个列出所有书籍的端点,以及另一个通过 ID 获取特定书籍的端点。这些端点使用我们的BookService与书籍数据进行交互。

app.MapGet("/", () => "Hello, World!");
app.MapGet("/books", ...);
app.MapGet("/books/{id}", ...);

运行应用程序

        最后,此行启动我们的应用程序,使其监听传入的请求。

app.Run();

        该Program.cs文件就像管弦乐队的指挥,确保我们的 Minimal API 的每个部分都能和谐地演奏。它证明了 .NET 8 中 Minimal API 的强大功能 - 简单而强大,使我们能够轻松构建高效且有效的 Web 服务。

退出时

    这些代码片段有效地演示了如何使用 .NET 中的 Minimal API 来创建干净、可维护且文档齐全的 Web 服务。通过利用依赖注入和清晰的路由,我们创建了一个易于理解和使用的 API。无论是列出所有书籍还是查找特定书籍,API 都能优雅高效地处理这些任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/903240.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【在Linux世界中追寻伟大的One Piece】Socket编程UDP(续)

目录 1 -> V3版本-实现简单聊天室 1 -> V3版本-实现简单聊天室 UdpServer.hpp #pragma once#include <iostream> #include <string> #include <cerrno> #include <cstring> #include <unistd.h> #include <strings.h> #include &…

XHCI 1.2b 规范摘要(六)

系列文章目录 XHCI 1.2b 规范摘要&#xff08;一&#xff09; XHCI 1.2b 规范摘要&#xff08;二&#xff09; XHCI 1.2b 规范摘要&#xff08;三&#xff09; XHCI 1.2b 规范摘要&#xff08;四&#xff09; XHCI 1.2b 规范摘要&#xff08;五&#xff09; XHCI 1.2b 规范摘要…

Anki插件Export deck to html的改造

在Anki中进行复习时&#xff0c;每次只能打开一条笔记。如果积累了很多笔记&#xff0c;有时候会有将它们集中输出成一个pdf进行阅读的想法。Anki插件Export deck to html&#xff08;安装ID&#xff1a;1897277426&#xff09;就有这个功能。但是&#xff0c;这个插件目前存在…

哈希表——unordered_set和unordered_map的封装

个人主页&#xff1a;敲上瘾-CSDN博客 个人专栏&#xff1a;游戏、数据结构、c语言基础、c学习、算法 在本章关于哈希表的设计在这里就随便提一点不再过多的讲解&#xff0c;而把重点放在封装部分。 目录 一、哈希表的设计 1.模板参数的设计 二、迭代器封装 1.迭代器简单…

理解计算机系统_异常控制流(一):异常

前言 以<深入理解计算机系统>(以下称“本书”)内容为基础&#xff0c;对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定 引入 异常控制流这章实际上是操作系统的一部分.操作系统简单的…

驱动学习(三)符号导出

1.什么是符号&#xff1f; 主要是指全局变量和函数 2.为什么要导出符号&#xff1f; ​ linux内核采用的是模块化的形式管理内核代码。内核中每个模块之间是相互独立的&#xff0c;也就是说A模块的全局变量和函数&#xff0c;B模块是无法访问的。若B模块想要使用A模块中的已有…

python爬虫——Selenium的基本使用

目录 一、Selenium的介绍 二、环境准备 1.安装Selenium 2.安装WebDriver 三、元素定位 1.常用定位元素的方法 2. 通过指定方式定位元素 四、窗口操作 1.最大化浏览器窗口 2.设置浏览器窗口大小 3.切换窗口或标签页 切换回主窗口 4. 关闭窗口 关闭当前窗口 关闭所…

java_方法重载、可变参数、作用域

方法重载 基本介绍 java 中允许同一个类中&#xff0c;多个同名方法的存在&#xff0c;但要求 形参列表不一致&#xff01; 比如&#xff1a;System.out.println(); out 是 PrintStream 类型 重载的好处 减轻了起名的麻烦减轻了记名的麻烦 案例 public class OverLoad01 …

SCI一区级 | Matlab实现SSA-TCN-LSTM-Attention多变量时间序列预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.基于SSA-TCN-LSTM-Attention麻雀搜索算法优化时间卷积长短期记忆神经网络融合注意力机制多变量时间序列预测&#xff0c;要求Matlab2023版以上&#xff0c;自注意力机制&#xff0c;一键单头注意力机制替换成多头注…

leetcode刷题(76-80)

算法是码农的基本功&#xff0c;也是各个大厂必考察的重点&#xff0c;让我们一起坚持写题吧。 遇事不决&#xff0c;可问春风&#xff0c;春风不语&#xff0c;即是本心。 我们在我们能力范围内&#xff0c;做好我们该做的事&#xff0c;然后相信一切都事最好的安排就可以啦…

深度生成模型 - 受限玻尔兹曼机(RBM)篇

前言 受限玻尔兹曼机&#xff08; Restricted Boltzmann Machine&#xff0c;RBM \text{Restricted Boltzmann Machine&#xff0c;RBM} Restricted Boltzmann Machine&#xff0c;RBM&#xff09;是深度学习领域中的一种重要模型&#xff0c;其起源于统计物理学&#xff0c;由…

【再谈设计模式】单例模式~唯一性的守护者

一、引言 在软件工程中&#xff0c;软件开发&#xff0c;设计模式是提高代码复用性和可维护性的有效工具。单例模式&#xff08;Singleton Pattern&#xff09;作为一种创建型设计模式&#xff0c;旨在确保一个类只有一个实例&#xff0c;并提供对该实例的全局访问。这一模式在…

如何在 Elasticsearch Ruby 客户端中使用 ES|QL Helper

作者&#xff1a;来自 Elastic Fernando Briano 了解如何使用 Elasticsearch Ruby 客户端编写 ES|QL 查询并处理其结果。 简介 Elasticsearch Ruby 客户端可用于编写 EQ|QL 查询&#xff0c;使处理从 esql.query 返回的数据更加容易。ES|QL 允许开发人员通过查询过滤、转换和分…

redis详细教程(3.ZSet,Bitmap,HyperLogLog)

ZSet Redis 的 ZSet&#xff08;有序集合&#xff09;是一种特殊的数据类型&#xff0c;它允许存储一系列不重复的字符串元素&#xff0c;并为每个元素关联一个分数&#xff08;score&#xff09;。这个分数用于对集合中的元素进行排序。ZSet 的特点是&#xff1a; 唯一性&am…

MYSQL-SQL-03-DQL(Data Query Language,数据查询语言)(单表查询)

DQL&#xff08;数据查询语言&#xff09; DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记录。 查询关键字: SELECT 在一个正常的业务系统中&#xff0c;查询操作的频次是要远高于增删改的&#xff0c;当我们去访…

Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置

文章目录 构建拓扑图配置IP地址配置路由器命令说明测试效果 构建拓扑图 1&#xff0c;添加2811路由器。 2&#xff0c;添加pc0。 3&#xff0c;使用交叉线连接路由器和pc&#xff08;注意线路端口&#xff09;。 4&#xff0c;使用配置线连接路由器和pc&#xff08;注意线路…

优化网站结构提升用户体验的关键要素

内容概要 在数字时代&#xff0c;网站的架构和用户体验密切相关。一个合理的网站结构不仅能帮助用户快速找到所需信息&#xff0c;还能提升整体的访问满意度。为了达到这一目的&#xff0c;网站需要强调几个关键要素。 首先&#xff0c;清晰的导航设计至关重要。导航应当直观…

Android Gradle

#1024程序员节&#xff5c;征文# Gradle 是一款强大的自动化构建工具&#xff0c;广泛应用于 Android 应用开发。它通过灵活的配置和丰富的插件系统&#xff0c;为项目构建提供了极大的便利。本文只是简单的介绍 Gradle 在 Android 开发中的使用&#xff0c;包括其核心概念、构…

微积分复习笔记 Calculus Volume 1 - 3.8 Implicit Differentiation

3.8 Implicit Differentiation - Calculus Volume 1 | OpenStax

Java——lambda表达式和StreamAPI

一、lambda 1. lambda表达式 1.1 Lambda表达式的使用举例: (o1,02)->Integer.compare(o1,o2); 1.2 Lambda表达式的格式举例: Lambda形参列表->lambda 1.3 Lambda表达式的格式 lambda操作符或箭头操作符 的左边:lambda形参列表&#xff0c;对应着要重写的接口中的…