preamble
be facing (us).NET
environment, there are already many options for generating WebApi proxy classes, such asOpenApi Generator
,NSwag
respond in singingRefitter
etc. Different tools generate code in slightly different styles and implementations, such asRefitter
The generated client isRefit
Style.
I prefer the Refit style of labeling and therefore prefer to use theRefitter
The 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 isKiota
This 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 for
OpenAPI
Generate 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 theNET8
SDK, then open the command line tool and install Kiota, the latest version has been updated to1.17.0
:
dotnet tool install --global
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
-
-l
is the client target language, theCSharp
just likeC#
-
-o
Indicates the folder where the generated proxy class file is saved -
-d
indicates the corresponding schema file. -
-n
Indicates 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.
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 namedSimpleAuthenticationProvider
class, which implements theIAuthenticationProvider
interface, 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 defaultAnonymousAuthenticationProvider
cap (a poem)BaseBearerTokenAuthenticationProvider
Two 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.
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 theApiClient
I'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!Kiota
respond in singingRefitter
,Maybe you'll like TA as much as I do!