首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

使用Kiota工具生成WebApi的代理类,以及接口调用的简单体验

编程知识
2024年08月21日 15:53

前言

当前.NET环境下,生成WebApi代理类的工具已经有很多选择了,比如OpenApi Generator,NSwagRefitter等,不同的工具生成的代码风格以及实现方式略有不同,比如Refitter生成的客户端是Refit风格.

本人比较喜欢Refit风格的标注风格因此还是比较喜欢使用Refitter的,TA生成的代码风格如下:

[Headers("Accept: application/json")]
[Get("/pet/{petId}")]
Task<Pet> GetPetById(long petId);

不过呢今天介绍的主角是Kiota,这个MS于2023年正式发布的一款代理生成工具,体验还是挺棒的,毫不夸张的说,算是这一领域的新贵了!

Kiota有以下诸多特性:

  • 支持多种语言:C#、CLI、Go、Java、PHP、Python、Ruby、Swift 和 TypeScript
  • 使用 OpenAPI 描述的全部功能
  • 能够轻松实施新的语言支持
  • 通过在核心库上构建,仅生成必要的源代码
  • 最小化外部依赖性
  • 使用 JSON Schema 描述生成基于基元的模型序列化/反序列化代码
  • 仅允许为OpenAPI描述的指定子集生成代码
  • 生成使 IDE 能够自动完成以帮助发现 API 资源的代码
  • 启用对 HTTP 功能的完全访问

命令行工具安装

接下来我们简单使用一下该工具:

当前以我们使用最多的Windows操作系统为例,首先安装NET8SDK,然后打开命令行工具,安装Kiota,当前最新版已经更新到了 1.17.0:

dotnet tool install --global Microsoft.OpenApi.Kiota

image

命令行生成代理

接下来我们随意创建一个NET8的MinimalApi项目,然后我们以Petshop3的Api为例,为了加快速度我们将接口Scheme文件下载到项目文件夹下:
文档地址为: https://petstore3.swagger.io/api/v3/openapi.json
当然了你也可以使用自己的WebApi;Schema文件下载完成后 我们使用命令行工具定位到对应的文件夹,然后键入如下命令:

kiota generate -l CSharp -o output -d petstore.json -n PetShops.V3

这里解释一下参数:

  • -l是客户端目标语言,CSharp就是C#
  • -o表示生成的代理类文件保存的文件夹
  • -d表示对应的schema文件,
  • -n表示生成的代理类的命名空间
    当然还有一些其他的参数这里就不一一列举,比如按需生成(排除保留指定的Api),有兴趣可以查看官方文档

如果没有其他问题,将会成功创建代理文件:
image

image

生成了代理类那使用起来就相当简单了:

调用生成的代理

接下来我们引用Kiota必须的几个类库:

<PackageReference Include="Microsoft.Kiota.Abstractions" />
<PackageReference Include="Microsoft.Kiota.Http.HttpClientLibrary" />
<PackageReference Include="Microsoft.Kiota.Serialization.Form" />
<PackageReference Include="Microsoft.Kiota.Serialization.Json"/>
<PackageReference Include="Microsoft.Kiota.Serialization.Multipart" />
<PackageReference Include="Microsoft.Kiota.Serialization.Text"  />

这里假设PetShop的接口需要简单验证才能访问:
我们首先定义一个名为SimpleAuthenticationProvider的类,该类实现了IAuthenticationProvider接口,代码如下:


internal class SimpleAuthenticationProvider(string baseUrl, string? userName, string? password) : IAuthenticationProvider
{
    public async Task AuthenticateRequestAsync(
        RequestInformation request,
        Dictionary<string, object>? additionalAuthenticationContext = null,
        CancellationToken cancellationToken = default)
    {
        using var httpClient = new HttpClient()
        {
            BaseAddress = new Uri(baseUrl)
        };
        httpClient.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/xml"));
        var authRequest = await httpClient.GetAsync(
            $"v3/user/login?username={userName}&password={password}", cancellationToken);

        if (!authRequest.IsSuccessStatusCode)
        {
            throw new Exception("Authentication failed");
        }
        var session = await authRequest.Content.ReadAsStringAsync(cancellationToken);

        Console.WriteLine($"session: {session}");
        await Task.CompletedTask;
        //todo:
    }
}

上面的代码很简单就是模拟一个登录,然后后面的请求就存在了session即可进行后续的接口调用,如果有些认证是JWT之内的这里可以把得到的Token传入到后续的Header中,当然认证请求务必缓存起来,不用每个接口调用都请求一次!

MS默认帮我们实现了AnonymousAuthenticationProviderBaseBearerTokenAuthenticationProvider两个认证Provider.

以下是简单的调用接口:

//分别调用条件查询Pet,以及根据Id查询指定的Pet
app.MapGet("/test", async () =>
{
    var baseUrl = "https://petstore3.swagger.io/api/v3";
    var userName = "万雅虎";
    var password = "12345";

    var adaptor = new HttpClientRequestAdapter(
        new SimpleAuthenticationProvider(baseUrl, userName, password))
    {
        BaseUrl = baseUrl
    };
    var api = new ApiClient(adaptor);
    var pets = await api.Pet.FindByStatus.GetAsync(x =>
    {
        x.QueryParameters.StatusAsGetStatusQueryParameterType =
        PetShops.V3.Pet.FindByStatus.GetStatusQueryParameterType.Sold;
    });

    var pet = await api.Pet[1].GetAsync();
    return new { Pets = pets, Pet = pet };
});

不出意外请求成功了:
image

注入ApiClient

当然上面的调用代码显得有一些粗糙,实际上大多数开发代码会使用到DI,
我们使用MS提供的示例代码扩展一下IServiceCollectionIHttpClientBuilder

using Microsoft.Kiota.Http.HttpClientLibrary;

/// <summary>
/// Service collection extensions for Kiota handlers.
/// </summary>
public static class KiotaServiceCollectionExtensions
{
    /// <summary>
    /// Adds the Kiota handlers to the service collection.
    /// </summary>
    /// <param name="services"><see cref="IServiceCollection"/> to add the services to</param>
    /// <returns><see cref="IServiceCollection"/> as per convention</returns>
    /// <remarks>The handlers are added to the http client by the <see cref="AttachKiotaHandlers(IHttpClientBuilder)"/> call, which requires them to be pre-registered in DI</remarks>
    public static IServiceCollection AddKiotaHandlers(this IServiceCollection services)
    {
        // Dynamically load the Kiota handlers from the Client Factory
        var kiotaHandlers = KiotaClientFactory.GetDefaultHandlerTypes();
        // And register them in the DI container
        foreach(var handler in kiotaHandlers)
        {
            services.AddTransient(handler);
        }

        return services;
    }

    /// <summary>
    /// Adds the Kiota handlers to the http client builder.
    /// </summary>
    /// <param name="builder"></param>
    /// <returns></returns>
    /// <remarks>
    /// Requires the handlers to be registered in DI by <see cref="AddKiotaHandlers(IServiceCollection)"/>.
    /// The order in which the handlers are added is important, as it defines the order in which they will be executed.
    /// </remarks>
    public static IHttpClientBuilder AttachKiotaHandlers(this IHttpClientBuilder builder)
    {
        // Dynamically load the Kiota handlers from the Client Factory
        var kiotaHandlers = KiotaClientFactory.GetDefaultHandlerTypes();
        // And attach them to the http client builder
        foreach(var handler in kiotaHandlers)
        {
            builder.AddHttpMessageHandler((sp) => (DelegatingHandler)sp.GetRequiredService(handler));
        }
        return builder;
    }
}

然后实现一个Api的ClientFactory:

//这里是伪代码,因为认证需要根据Api按需实现,比如这里是匿名请求
public class PetShopClientFactory
{
    private readonly IAuthenticationProvider _authenticationProvider;
    private readonly HttpClient _httpClient;

    public PetShopClientFactory(HttpClient httpClient)
    {
        _authenticationProvider = new AnonymousAuthenticationProvider();
        _httpClient = httpClient;
    }

    public ApiClient GetClient() {
      return new ApiClient(new HttpClientRequestAdapter(_authenticationProvider, httpClient: _httpClient));
    }
}

然后在服务注册中添加如下代码:


// ----------- Add this part to register the generated client -----------
// Add Kiota handlers to the dependency injection container
builder.Services.AddKiotaHandlers();

// Register the factory for the PetShop client
builder.Services.AddHttpClient<PetShopClientFactory>((sp, client) => {
    // Set the base address and accept header
    // or other settings on the http client
    client.BaseAddress = new Uri("https://petstore3.swagger.io/api/v3");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
}).AttachKiotaHandlers(); // Attach the Kiota handlers to the http client, this is to enable all the Kiota features.

// Register the PetShop client
builder.Services.AddTransient(sp => sp.GetRequiredService<PetShopClientFactory>().GetClient());
// ----------- Add this part to register the generated client end -------

最后我们在使用的地方注入ApiClient即可!

总结

对于不同的代理类和工具选型这里不做推荐,能满足项目需求以及节省开发时间即可,不过如果你有兴趣倒是推荐体验一下KiotaRefitter,没准你会和我一样喜欢上TA!

From:https://www.cnblogs.com/vipwan/p/18372027
本文地址: http://shuzixingkong.net/article/1305
0评论
提交 加载更多评论
其他文章 poi的excel导出
poi的excel导出 这个导出依赖于模板文件,可便捷设置表头样式。 也可以不使用模板,直接创建。 1.引入poi依赖 &lt;dependency&gt; &lt;groupId&gt;org.apache.poi&lt;/groupId&gt; &lt;artifactId&gt;poi&lt;
poi的excel导出 poi的excel导出
2024-08-21:用go语言,给定一个从 0 开始索引的整数数组 nums 和一个整数 k,请设计一个算法来使得数组中的所有元素都大于或等于 k,返回所需的最少操作次数。 每次操作可以执行以下步骤
2024-08-21:用go语言,给定一个从 0 开始索引的整数数组 nums 和一个整数 k,请设计一个算法来使得数组中的所有元素都大于或等于 k,返回所需的最少操作次数。 每次操作可以执行以下步骤: 1.选择数组中最小的两个整数 x 和 y。 2.从数组中删除 x 和 y。 3.计算 min(x
2024-08-21:用go语言,给定一个从 0 开始索引的整数数组 nums 和一个整数 k,请设计一个算法来使得数组中的所有元素都大于或等于 k,返回所需的最少操作次数。 每次操作可以执行以下步骤 2024-08-21:用go语言,给定一个从 0 开始索引的整数数组 nums 和一个整数 k,请设计一个算法来使得数组中的所有元素都大于或等于 k,返回所需的最少操作次数。 每次操作可以执行以下步骤
会员力量:非常感谢12+1位园友成为终身会员
昨天晚上18点左右,我们在 https://cnblogs.vip/ 上线了终身会员——终身PLUS会员与终身VIP会员。上线后,我们在会员微信群里发了群公告,企业微信发了朋友圈,在「.NET社群」微信群中发了一条消息。 到昨天晚上23:30,一共有12位园友成为终身会员,做二十年梦也没想到一个晚上
会员力量:非常感谢12+1位园友成为终身会员
【VMware VCF】VCF 5.2:部署整合架构的SDDC。
VMware 前不久发布了 VMware Cloud Foundation 5.2 版本,并带来了许多功能的升级,比如支持 vSAN Max 分解存储,管理工作负载域支持 vSAN ESA 延伸集群,通过 VCF Import 工具将现有环境中的 vSphere/vSAN 集群直接转换成管理域或者导
【VMware VCF】VCF 5.2:部署整合架构的SDDC。 【VMware VCF】VCF 5.2:部署整合架构的SDDC。 【VMware VCF】VCF 5.2:部署整合架构的SDDC。
使用Packer构建镜像
什么是Packer Packer 是一个强大的工具,它可以帮助我们轻松地构建各种类型的镜像,如虚拟机镜像、Docker 镜像等。 Packer 的工作原理是通过定义一个配置文件,该文件描述了要构建的镜像的特征和要求。然后 Packer 使用这个配置文件来执行一系列的步骤,例如安装必要的软件、配置系统
使用Packer构建镜像 使用Packer构建镜像 使用Packer构建镜像
目标追踪 ByteTrack 算法详细流程分析(看街拍追踪演示视频)
ByteTrack是字节跳动与2021年10月份公开的一个全新的多目标跟踪算法,原论文是《ByteTrack: Multi-Object Tracking by Associating Every Detection Box》。 ByteTrak的MOTA和FPS等指标上都实现了较好的性能,要优于现
目标追踪 ByteTrack 算法详细流程分析(看街拍追踪演示视频) 目标追踪 ByteTrack 算法详细流程分析(看街拍追踪演示视频) 目标追踪 ByteTrack 算法详细流程分析(看街拍追踪演示视频)
P7706 文文的摄影布置 题解
P7706 文文的摄影布置 题解 原题 读完题,发现是线段树。单点修改+区间查询。 不过查询的值有些奇怪,就是了,我们考虑用线段树维护这个 ψ 值(下称待求值)。 对于一个区间的待求值,大概有四种情况: 如上图四种情况分别为: 待求值最大值在左区间 待求值最大值在右区间 \(a_i与b_j\) 在左
P7706 文文的摄影布置 题解
WPF:MVVM的由来与属性绑定的过程
WPF:MVVM的由来与属性绑定的过程 1、MVVM (1)MVVM是什么? ​ MVVM(Model-View-ViewModel)是一种软件架构设计模式MVVM模式。有助于分离应用程序的业务逻辑和用户界面层,使得开发过程更易于管理,同时也便于单元测试。 Model? 现实世界中对象的抽象结果。
WPF:MVVM的由来与属性绑定的过程 WPF:MVVM的由来与属性绑定的过程 WPF:MVVM的由来与属性绑定的过程