Skip to content

Commit 7b139cb

Browse files
committed
Add documentation for kiota
1 parent 19ab048 commit 7b139cb

File tree

2 files changed

+120
-31
lines changed

2 files changed

+120
-31
lines changed

docs/usage/openapi-client.md

Lines changed: 119 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,54 @@
1-
# OpenAPI Client
1+
# OpenAPI clients
22

3-
You can generate a JSON:API client in various programming languages from the [OpenAPI specification](https://swagger.io/specification/) file that JsonApiDotNetCore APIs provide.
3+
After [enabling OpenAPI](~/usage/openapi.md), you can generate a JSON:API client for your API in various programming languages.
44

5-
For C# .NET clients generated using [NSwag](https://github.com/RicoSuter/NSwag), we provide an additional package
6-
that provides workarounds for NSwag bugs and introduces support for partial PATCH/POST requests.
7-
The concern here is that a property on a generated C# class being `null` could either mean: "set the value to `null`
8-
in the request" or: "this is `null` because I never touched it".
5+
The following generators are supported, though you may try others as well:
6+
- [NSwag](https://github.com/RicoSuter/NSwag): Produces clients for C# and TypeScript
7+
- [Kiota](https://learn.microsoft.com/en-us/openapi/kiota/overview): Produces clients for C#, Go, Java, PHP, Python, Ruby, Swift and TypeScript
8+
9+
# [NSwag](#tab/nswag)
10+
11+
For C# clients, we provide an additional package that provides workarounds for bugs in NSwag and enables using partial PATCH/POST requests.
12+
13+
To add it to your project, run the following command:
14+
```
15+
dotnet add package JsonApiDotNetCore.OpenApi.Client.NSwag
16+
```
17+
18+
# [Kiota](#tab/kiota)
19+
20+
For C# clients, we provide an additional package that provides workarounds for bugs in Kiota.
21+
22+
To add it to your project, run the following command:
23+
```
24+
dotnet add package JsonApiDotNetCore.OpenApi.Client.Kiota
25+
```
26+
27+
---
928

1029
## Getting started
1130

31+
To generate your C# client, follow the steps below.
32+
33+
# [NSwag](#tab/nswag)
34+
1235
### Visual Studio
1336

1437
The easiest way to get started is by using the built-in capabilities of Visual Studio.
15-
The next steps describe how to generate a JSON:API client library and use our package.
38+
The following steps describe how to generate and use a JSON:API client in C#, using our package.
1639

1740
1. In **Solution Explorer**, right-click your client project, select **Add** > **Service Reference** and choose **OpenAPI**.
1841

1942
2. On the next page, specify the OpenAPI URL to your JSON:API server, for example: `http://localhost:14140/swagger/v1/swagger.json`.
20-
Specify `ExampleApiClient` as class name, optionally provide a namespace and click **Finish**.
43+
Specify `ExampleApiClient` as the class name, optionally provide a namespace and click **Finish**.
2144
Visual Studio now downloads your swagger.json and updates your project file.
2245
This adds a pre-build step that generates the client code.
2346

2447
> [!TIP]
2548
> To later re-download swagger.json and regenerate the client code,
2649
> right-click **Dependencies** > **Manage Connected Services** and click the **Refresh** icon.
2750
28-
3. Although not strictly required, we recommend to run package update now, which fixes some issues.
51+
3. Although not strictly required, we recommend running package update now, which fixes some issues.
2952

3053
> [!WARNING]
3154
> NSwag v14 is currently *incompatible* with JsonApiDotNetCore (tracked [here](https://github.com/RicoSuter/NSwag/issues/4662)). Stick with v13.x for the moment.
@@ -36,7 +59,7 @@ The next steps describe how to generate a JSON:API client library and use our pa
3659
dotnet add package JsonApiDotNetCore.OpenApi.Client.NSwag
3760
```
3861
39-
5. Add the next line inside the **OpenApiReference** section in your project file:
62+
5. Add the following line inside the **OpenApiReference** section in your project file:
4063
4164
```xml
4265
<Options>/GenerateExceptionClasses:false /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client.NSwag</Options>
@@ -62,10 +85,6 @@ The next steps describe how to generate a JSON:API client library and use our pa
6285
}
6386
```
6487
65-
> [!TIP]
66-
> The project at src/Examples/OpenApiNSwagClientExample contains an enhanced version that logs the HTTP requests and responses.
67-
> Additionally, the example shows how to write the swagger.json file to disk when building the server, which is imported from the client project. This keeps the server and client automatically in sync, which is handy when both are in the same solution.
68-
6988
7. Add code that calls one of your JSON:API endpoints.
7089
7190
```c#
@@ -121,42 +140,64 @@ The next steps describe how to generate a JSON:API client library and use our pa
121140
}
122141
```
123142
143+
> [!TIP]
144+
> The [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiNSwagClientExample) contains an enhanced version that uses `IHttpClientFactory` for [scalability](https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory) and [resiliency](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests#use-polly-based-handlers) and logs the HTTP requests and responses.
145+
> Additionally, the example shows how to write the swagger.json file to disk when building the server, which is imported from the client project. This keeps the server and client automatically in sync, which is handy when both are in the same solution.
146+
124147
### Other IDEs
125148
126-
When using the command-line, you can try the [Microsoft.dotnet-openapi Global Tool](https://docs.microsoft.com/en-us/aspnet/core/web-api/microsoft.dotnet-openapi?view=aspnetcore-5.0).
149+
When using the command line, you can try the [Microsoft.dotnet-openapi Global Tool](https://docs.microsoft.com/en-us/aspnet/core/web-api/microsoft.dotnet-openapi?view=aspnetcore-5.0).
127150
128-
Alternatively, the next section shows what to add to your client project file directly:
151+
Alternatively, the following section shows what to add to your client project file directly:
129152
130153
```xml
131154
<ItemGroup>
132-
<PackageReference Include="Microsoft.Extensions.ApiDescription.Client" Version="7.0.11">
133-
<PrivateAssets>all</PrivateAssets>
134-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
135-
</PackageReference>
136-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
137-
<PackageReference Include="NSwag.ApiDescription.Client" Version="13.20.0">
138-
<PrivateAssets>all</PrivateAssets>
139-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
140-
</PackageReference>
155+
<PackageReference Include="Microsoft.Extensions.ApiDescription.Client" Version="8.0.*" PrivateAssets="all" />
156+
<PackageReference Include="Newtonsoft.Json" Version="13.0.*" />
157+
<PackageReference Include="NSwag.ApiDescription.Client" Version="13.20.*" PrivateAssets="all" />
141158
</ItemGroup>
142159
143160
<ItemGroup>
144-
<OpenApiReference Include="OpenAPIs\swagger.json" CodeGenerator="NSwagCSharp" ClassName="ExampleApiClient">
161+
<OpenApiReference Include="OpenAPIs\swagger.json">
145162
<SourceUri>http://localhost:14140/swagger/v1/swagger.json</SourceUri>
163+
<CodeGenerator>NSwagCSharp</CodeGenerator>
164+
<ClassName>ExampleApiClient</ClassName>
165+
<OutputPath>ExampleApiClient.cs</OutputPath>
146166
</OpenApiReference>
147167
</ItemGroup>
148168
```
149169

150170
From here, continue from step 3 in the list of steps for Visual Studio.
151171

172+
# [Kiota](#tab/kiota)
173+
174+
To generate your C# client, install the Kiota tool by following the steps at https://learn.microsoft.com/en-us/openapi/kiota/install#install-as-net-tool.
175+
176+
Next, generate client code by running the [command line tool](https://learn.microsoft.com/en-us/openapi/kiota/using#client-generation). For example:
177+
178+
```
179+
dotnet kiota generate --language CSharp --class-name ExampleApiClient --output ./GeneratedCode --backing-store --exclude-backward-compatible --clean-output --clear-cache --openapi ..\JsonApiDotNetCoreExample\GeneratedSwagger\JsonApiDotNetCoreExample.json
180+
```
181+
182+
> [!CAUTION]
183+
> The `--backing-store` switch is needed for JSON:API partial PATCH/POST requests to work correctly.
184+
185+
Kiota is pretty young and therefore still rough around the edges. At the time of writing, there are various bugs, for which we have workarounds
186+
in place. For a full example, see the [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiKiotaClientExample).
187+
188+
---
189+
152190
## Configuration
153191

154-
### NSwag
192+
Various switches enable you to tweak the client generation to your needs. See the section below for an overview.
193+
194+
# [NSwag](#tab/nswag)
155195

156196
The `OpenApiReference` element in the project file accepts an `Options` element to pass additional settings to the client generator,
157197
which are listed [here](https://github.com/RicoSuter/NSwag/blob/master/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToCSharpClientCommand.cs).
198+
A guide with common best practices is available [here](https://stevetalkscode.co.uk/openapireference-commands).
158199

159-
For example, the next section puts the generated code in a namespace and generates an interface (which is handy for dependency injection):
200+
For example, the following section puts the generated code in a namespace and generates an interface (which is handy for dependency injection):
160201

161202
```xml
162203
<OpenApiReference Include="swagger.json">
@@ -167,10 +208,37 @@ For example, the next section puts the generated code in a namespace and generat
167208
</OpenApiReference>
168209
```
169210

211+
Likewise, you can enable nullable reference types by adding `/GenerateNullableReferenceTypes:true`, optionally combined with `/GenerateOptionalParameters:true`.
212+
213+
# [Kiota](#tab/kiota)
214+
215+
The available command-line switches for Kiota are described [here](https://learn.microsoft.com/en-us/openapi/kiota/using#client-generation).
216+
217+
At the time of writing, Kiota provides [no official integration](https://github.com/microsoft/kiota/issues/3005) with MSBuild.
218+
Our [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiKiotaClientExample) takes a stab at it, although it has glitches. If you're an MSBuild expert, please help out!
219+
220+
```xml
221+
<Target Name="KiotaRunTool" BeforeTargets="BeforeCompile;CoreCompile" Condition="$(DesignTimeBuild) != true And $(BuildingProject) == true">
222+
<Exec
223+
Command="dotnet kiota generate --language CSharp --class-name ExampleApiClient --namespace-name OpenApiKiotaClientExample.GeneratedCode --output ./GeneratedCode --backing-store --exclude-backward-compatible --clean-output --clear-cache --openapi ..\JsonApiDotNetCoreExample\GeneratedSwagger\JsonApiDotNetCoreExample.json" />
224+
225+
<ItemGroup>
226+
<!-- This isn't entirely reliable: may require a second build after the source swagger.json has changed, to get rid of compile errors. -->
227+
<Compile Remove="**\GeneratedCode\**\*.cs" />
228+
<Compile Include="**\GeneratedCode\**\*.cs" />
229+
</ItemGroup>
230+
</Target>
231+
```
232+
233+
---
234+
170235
## Headers and caching
171236

172-
To use [ETags for caching](~/usage/caching.md), NSwag needs extra settings to make response headers accessible.
173-
Specify the following in the `<Options>` element of your project file:
237+
The use of HTTP headers varies per client generator. To use [ETags for caching](~/usage/caching.md), see the notes below.
238+
239+
# [NSwag](#tab/nswag)
240+
241+
NSwag needs extra settings to make response headers accessible. Specify the following in the `<Options>` element of your project file:
174242

175243
```
176244
/GenerateExceptionClasses:false /WrapResponses:true /GenerateResponseClasses:false /ResponseClass:ApiResponse /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client.NSwag
@@ -197,3 +265,24 @@ The response of the first API call contains both data and an ETag header, which
197265
That ETag gets passed to the second API call. This enables the server to detect if something changed, which optimizes
198266
network usage: no data is sent back, unless is has changed.
199267
If you only want to ask whether data has changed without fetching it, use a HEAD request instead.
268+
269+
# [Kiota](#tab/kiota)
270+
271+
Use `HeadersInspectionHandlerOption` to gain access to response headers. For example:
272+
273+
```c#
274+
var headerInspector = new HeadersInspectionHandlerOption
275+
{
276+
InspectResponseHeaders = true
277+
};
278+
279+
var responseDocument = await apiClient.Api.People.GetAsync(configuration => configuration.Options.Add(headerInspector));
280+
281+
string eTag = headerInspector.ResponseHeaders["ETag"].Single();
282+
```
283+
284+
Due to a [bug in Kiota](https://github.com/microsoft/kiota/issues/4190), a try/catch block is needed additionally to make this work.
285+
286+
For a full example, see the [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiKiotaClientExample).
287+
288+
---

docs/usage/toc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# [Common Pitfalls](common-pitfalls.md)
2727

2828
# [OpenAPI](openapi.md)
29-
## [Client](openapi-client.md)
29+
## [Clients](openapi-client.md)
3030

3131
# Extensibility
3232
## [Layer Overview](extensibility/layer-overview.md)

0 commit comments

Comments
 (0)