Location>code7788 >text

Using Kiota tools to generate WebApi proxy class , and interface calls to a simple experience

Popularity:640 ℃/2024-08-21 16:57:20
preamble

be facing (us).NETenvironment, there are already many options for generating WebApi proxy classes, such asOpenApi Generator,NSwagrespond in singingRefitteretc. Different tools generate code in slightly different styles and implementations, such asRefitterThe generated client isRefitStyle.

I prefer the Refit style of labeling and therefore prefer to use theRefitterThe code style generated by TA is as follows.

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

However, the main character of today's presentation isKiotaThis proxy generation tool, officially released by MS in 2023, is still a great experience, and is, without exaggeration, a newcomer to the field!

Kiota has a number of features.

  • Multiple languages are supported:C#CLI, Go, Java, PHP, Python, Ruby, Swift sumTypeScript
  • Use the full functionality of the OpenAPI description
  • Ability to easily implement new language support
  • Generate only the necessary source code by building on the core library
  • Minimize external dependencies
  • Generate primitive-based model serialization/deserialization code using JSON Schema descriptions
  • Only allowed forOpenAPIGenerate code for a specified subset of the description
  • Generate code that the IDE can automate to help discover API resources
  • Enable full access to HTTP functionality
Command Line Tool Installation

Let's take a quick look at the tool.

Currently we use the most popular Windows operating system as an example, first install theNET8SDK, then open the command line tool and install Kiota, the latest version has been updated to1.17.0:

dotnet tool install --global 

image

Command Line Generation Agent

Let's create a MinimalApi project for NET8, and then we'll use the Petshop3 Api as an example. In order to speed things up, we'll download the interface Scheme file into the project folder.
The document address is./api/v3/
Of course, you can also use your own WebApi; after the Schema file is downloaded, we use the command line tool to locate the corresponding folder, and then type the following command.

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

Here's an explanation of the parameters: the

  • -lis the client target language, theCSharpjust likeC#
  • -oIndicates the folder where the generated proxy class file is saved
  • -dindicates the corresponding schema file.
  • -nIndicates the namespace of the generated proxy class
    Of course there are some other parameters are not listed here, such as on-demand generation (excluding the retention of the specified Api), interested in checking out theofficial document

If there are no other problems, the proxy file will be created successfully.
image

image

Once the proxy class is generated it's fairly simple to use: the

Calling the generated proxy

Next we quote a few libraries that are necessary for Kiota.

<PackageReference Include="" />
<PackageReference Include="" />
<PackageReference Include="" />
<PackageReference Include=""/>
<PackageReference Include="" />
<PackageReference Include=""  />

It is assumed here that PetShop's interface requires simple authentication to access:.
We start by defining a file namedSimpleAuthenticationProviderclass, which implements theIAuthenticationProviderinterface, the code is as follows.


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)
        };
        (
            new MediaTypeWithQualityHeaderValue("application/xml"));
        var authRequest = await (
            $"v3/user/login?username={userName}&password={password}", cancellationToken);

        if (!)
        {
            throw new Exception("Authentication failed");
        }
        var session = await (cancellationToken);

        ($"session: {session}");
        await ;
        //todo:
    }
}

The above code is very simple is to simulate a login, and then the back of the request on the existence of the session can be followed by the interface call, if some of the authentication is within the JWT here you can get the Token into the subsequent Header, of course, the authentication request to be sure to cache up, do not have to call each interface to request a time!

MS does this for us by defaultAnonymousAuthenticationProvidercap (a poem)BaseBearerTokenAuthenticationProviderTwo authentication Providers.

The following is a simple call to the interface.

//Call the conditional query separatelyPet,and on the basis ofIdQuery the specifiedPet
("/test", async () =>
{
    var baseUrl = "/api/v3";
    var userName = "Wan Yashoo (1933-), PRC politician, prime minister from 2008";
    var password = "12345";

    var adaptor = new HttpClientRequestAdapter(
        new SimpleAuthenticationProvider(baseUrl, userName, password))
    {
        BaseUrl = baseUrl
    };
    var api = new ApiClient(adaptor);
    var pets = await (x =>
    {
         =
        PetShops.;
    });

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

Unsurprisingly, the request was successful.
image

Inject ApiClient

Of course, the call code above is a bit crude, but in fact most development code will use theDI,
Let's extend it with the sample code provided by MSIServiceCollection

using ;

/// <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 = ();
        // And register them in the DI container
        foreach(var handler in kiotaHandlers)
        {
            (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 = ();
        // And attach them to the http client builder
        foreach(var handler in kiotaHandlers)
        {
            ((sp) => (DelegatingHandler)(handler));
        }
        return builder;
    }
}

Then implement an Api's ClientFactory.

//Here is the pseudo-code,Because certification needs to be based onApion-demand realization,For example, here's an anonymous request
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));
    }
}

Then add the following code to the service registration.


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

// Register the factory for the GitHub client
<PetShopClientFactory>((sp, client) => {
    // Set the base address and accept header
    // or other settings on the http client
     = new Uri("/api/v3");
    ("Accept", "application/json");
}).AttachKiotaHandlers(); // Attach the Kiota handlers to the http client, this is to enable all the Kiota features.

// Register the GitHub client
(sp => <PetShopClientFactory>().GetClient());
// ----------- Add this part to register the generated client end -------

Finally we inject theApiClientI'll do it!

summarize

For different types of agents and tools to choose this is not recommended to meet the needs of the project as well as to save development time can be, but if you are interested in it is recommended to experience!Kiotarespond in singingRefitter,Maybe you'll like TA as much as I do!