diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 9658fff117..4ceebfab3b 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -25,6 +25,12 @@
"commands": [
"docfx"
]
+ },
+ "microsoft.openapi.kiota": {
+ "version": "1.11.1",
+ "commands": [
+ "kiota"
+ ]
}
}
}
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
index 1f6c60ff78..2780241e04 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,6 +1,5 @@
# When running OpenAPI tests, these committed files are downloaded and written to disk (so we'll know when something changes).
# On Windows, these text files are auto-converted to crlf on git fetch, while the written downloaded files use lf line endings.
# Therefore, running the tests on Windows creates local changes. Staging them auto-converts back to crlf, which undoes the changes.
-# To avoid this annoyance, the next lines opt out of the auto-conversion and force to lf.
-swagger.g.json text eol=lf
+# To avoid this annoyance, the next line opts out of the auto-conversion and forces line endings to lf.
**/GeneratedSwagger/*.json text eol=lf
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index f12a02041b..55d430a67c 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -35,6 +35,9 @@ jobs:
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
+ - name: Restore .NET tools
+ run: |
+ dotnet tool restore
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
diff --git a/.gitignore b/.gitignore
index 85bd0f1080..c1757fc159 100644
--- a/.gitignore
+++ b/.gitignore
@@ -423,3 +423,6 @@ FodyWeavers.xsd
**/.idea/**/httpRequests/
**/.idea/**/dataSources/
!**/.idea/**/codeStyles/*
+
+# Workaround for https://github.com/microsoft/kiota/issues/4228
+kiota-lock.json
diff --git a/JsonApiDotNetCore.sln b/JsonApiDotNetCore.sln
index 15ae0a00e3..3e092342c6 100644
--- a/JsonApiDotNetCore.sln
+++ b/JsonApiDotNetCore.sln
@@ -66,13 +66,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonApiDotNetCore.OpenApi",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiTests", "test\OpenApiTests\OpenApiTests.csproj", "{B693DE14-BB28-496F-AB39-B4E674ABCA80}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonApiDotNetCore.OpenApi.Client", "src\JsonApiDotNetCore.OpenApi.Client\JsonApiDotNetCore.OpenApi.Client.csproj", "{5ADAA902-5A75-4ECB-B4B4-03291D63CE9C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonApiDotNetCore.OpenApi.Client.NSwag", "src\JsonApiDotNetCore.OpenApi.Client.NSwag\JsonApiDotNetCore.OpenApi.Client.NSwag.csproj", "{5ADAA902-5A75-4ECB-B4B4-03291D63CE9C}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonApiDotNetCoreExampleClient", "src\Examples\JsonApiDotNetCoreExampleClient\JsonApiDotNetCoreExampleClient.csproj", "{7FC5DFA3-6F66-4FD8-820D-81E93856F252}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiNSwagClientExample", "src\Examples\OpenApiNSwagClientExample\OpenApiNSwagClientExample.csproj", "{7FC5DFA3-6F66-4FD8-820D-81E93856F252}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiClientTests", "test\OpenApiClientTests\OpenApiClientTests.csproj", "{77F98215-3085-422E-B99D-4C404C2114CF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiNSwagClientTests", "test\OpenApiNSwagClientTests\OpenApiNSwagClientTests.csproj", "{77F98215-3085-422E-B99D-4C404C2114CF}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiEndToEndTests", "test\OpenApiEndToEndTests\OpenApiEndToEndTests.csproj", "{3BA4F9B9-3D90-44B5-B09C-28D98E0B4225}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiNSwagEndToEndTests", "test\OpenApiNSwagEndToEndTests\OpenApiNSwagEndToEndTests.csproj", "{3BA4F9B9-3D90-44B5-B09C-28D98E0B4225}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonApiDotNetCore.OpenApi.Client.Kiota", "src\JsonApiDotNetCore.OpenApi.Client.Kiota\JsonApiDotNetCore.OpenApi.Client.Kiota.csproj", "{617FCA5D-A2DE-4083-B373-ADCA9901059F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiKiotaClientExample", "src\Examples\OpenApiKiotaClientExample\OpenApiKiotaClientExample.csproj", "{39DEAFE8-AE29-48E5-A67D-73776D70FC82}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenApiKiotaEndToEndTests", "test\OpenApiKiotaEndToEndTests\OpenApiKiotaEndToEndTests.csproj", "{FD86C676-3D80-4971-8D8C-B0729B2251F6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -396,6 +402,42 @@ Global
{3BA4F9B9-3D90-44B5-B09C-28D98E0B4225}.Release|x64.Build.0 = Release|Any CPU
{3BA4F9B9-3D90-44B5-B09C-28D98E0B4225}.Release|x86.ActiveCfg = Release|Any CPU
{3BA4F9B9-3D90-44B5-B09C-28D98E0B4225}.Release|x86.Build.0 = Release|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Debug|x64.Build.0 = Debug|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Debug|x86.Build.0 = Debug|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Release|x64.ActiveCfg = Release|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Release|x64.Build.0 = Release|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Release|x86.ActiveCfg = Release|Any CPU
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F}.Release|x86.Build.0 = Release|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Debug|x64.Build.0 = Debug|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Debug|x86.Build.0 = Debug|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Release|x64.ActiveCfg = Release|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Release|x64.Build.0 = Release|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Release|x86.ActiveCfg = Release|Any CPU
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82}.Release|x86.Build.0 = Release|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Debug|x64.Build.0 = Debug|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Debug|x86.Build.0 = Debug|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Release|x64.ActiveCfg = Release|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Release|x64.Build.0 = Release|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Release|x86.ActiveCfg = Release|Any CPU
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -427,6 +469,9 @@ Global
{7FC5DFA3-6F66-4FD8-820D-81E93856F252} = {026FBC6C-AF76-4568-9B87-EC73457899FD}
{77F98215-3085-422E-B99D-4C404C2114CF} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
{3BA4F9B9-3D90-44B5-B09C-28D98E0B4225} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
+ {617FCA5D-A2DE-4083-B373-ADCA9901059F} = {7A2B7ADD-ECB5-4D00-AA6A-D45BD11C97CF}
+ {39DEAFE8-AE29-48E5-A67D-73776D70FC82} = {026FBC6C-AF76-4568-9B87-EC73457899FD}
+ {FD86C676-3D80-4971-8D8C-B0729B2251F6} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A2421882-8F0A-4905-928F-B550B192F9A4}
diff --git a/JsonApiDotNetCore.sln.DotSettings b/JsonApiDotNetCore.sln.DotSettings
index 9b756680ec..8ab8b0cf0c 100644
--- a/JsonApiDotNetCore.sln.DotSettings
+++ b/JsonApiDotNetCore.sln.DotSettings
@@ -670,6 +670,7 @@ $left$ = $right$;
True
True
True
+ True
True
True
True
diff --git a/docs/usage/openapi-client.md b/docs/usage/openapi-client.md
index 2acd8f2fe6..0ba44d20d6 100644
--- a/docs/usage/openapi-client.md
+++ b/docs/usage/openapi-client.md
@@ -1,23 +1,46 @@
-# OpenAPI Client
+# OpenAPI clients
-You can generate a JSON:API client in various programming languages from the [OpenAPI specification](https://swagger.io/specification/) file that JsonApiDotNetCore APIs provide.
+After [enabling OpenAPI](~/usage/openapi.md), you can generate a JSON:API client for your API in various programming languages.
-For C# .NET clients generated using [NSwag](https://github.com/RicoSuter/NSwag), we provide an additional package
-that provides workarounds for NSwag bugs and introduces support for partial PATCH/POST requests.
-The concern here is that a property on a generated C# class being `null` could either mean: "set the value to `null`
-in the request" or: "this is `null` because I never touched it".
+The following generators are supported, though you may try others as well:
+- [NSwag](https://github.com/RicoSuter/NSwag): Produces clients for C# and TypeScript
+- [Kiota](https://learn.microsoft.com/en-us/openapi/kiota/overview): Produces clients for C#, Go, Java, PHP, Python, Ruby, Swift and TypeScript
+
+# [NSwag](#tab/nswag)
+
+For C# clients, we provide an additional package that provides workarounds for bugs in NSwag and enables using partial PATCH/POST requests.
+
+To add it to your project, run the following command:
+```
+dotnet add package JsonApiDotNetCore.OpenApi.Client.NSwag
+```
+
+# [Kiota](#tab/kiota)
+
+For C# clients, we provide an additional package that provides workarounds for bugs in Kiota.
+
+To add it to your project, run the following command:
+```
+dotnet add package JsonApiDotNetCore.OpenApi.Client.Kiota
+```
+
+---
## Getting started
+To generate your C# client, follow the steps below.
+
+# [NSwag](#tab/nswag)
+
### Visual Studio
The easiest way to get started is by using the built-in capabilities of Visual Studio.
-The next steps describe how to generate a JSON:API client library and use our package.
+The following steps describe how to generate and use a JSON:API client in C#, using our package.
1. In **Solution Explorer**, right-click your client project, select **Add** > **Service Reference** and choose **OpenAPI**.
2. On the next page, specify the OpenAPI URL to your JSON:API server, for example: `http://localhost:14140/swagger/v1/swagger.json`.
- Specify `ExampleApiClient` as class name, optionally provide a namespace and click **Finish**.
+ Specify `ExampleApiClient` as the class name, optionally provide a namespace and click **Finish**.
Visual Studio now downloads your swagger.json and updates your project file.
This adds a pre-build step that generates the client code.
@@ -25,7 +48,7 @@ The next steps describe how to generate a JSON:API client library and use our pa
> To later re-download swagger.json and regenerate the client code,
> right-click **Dependencies** > **Manage Connected Services** and click the **Refresh** icon.
-3. Although not strictly required, we recommend to run package update now, which fixes some issues.
+3. Although not strictly required, we recommend running package update now, which fixes some issues.
> [!WARNING]
> NSwag v14 is currently *incompatible* with JsonApiDotNetCore (tracked [here](https://github.com/RicoSuter/NSwag/issues/4662)). Stick with v13.x for the moment.
@@ -33,13 +56,13 @@ The next steps describe how to generate a JSON:API client library and use our pa
4. Add our client package to your project:
```
- dotnet add package JsonApiDotNetCore.OpenApi.Client
+ dotnet add package JsonApiDotNetCore.OpenApi.Client.NSwag
```
-5. Add the next line inside the **OpenApiReference** section in your project file:
+5. Add the following line inside the **OpenApiReference** section in your project file:
```xml
- /GenerateExceptionClasses:false /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client
+ /GenerateExceptionClasses:false /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client.NSwag
```
6. Add the following glue code to connect our package with your generated code.
@@ -50,7 +73,7 @@ The next steps describe how to generate a JSON:API client library and use our pa
> For example, add `namespace GeneratedCode;` below the `using` lines.
```c#
- using JsonApiDotNetCore.OpenApi.Client;
+ using JsonApiDotNetCore.OpenApi.Client.NSwag;
using Newtonsoft.Json;
partial class ExampleApiClient : JsonApiClient
@@ -62,10 +85,6 @@ The next steps describe how to generate a JSON:API client library and use our pa
}
```
- > [!TIP]
- > The project at src/Examples/JsonApiDotNetCoreExampleClient contains an enhanced version that logs the HTTP requests and responses.
- > 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.
-
7. Add code that calls one of your JSON:API endpoints.
```c#
@@ -121,42 +140,64 @@ The next steps describe how to generate a JSON:API client library and use our pa
}
```
+> [!TIP]
+> 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.
+> 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.
+
### Other IDEs
-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).
+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).
-Alternatively, the next section shows what to add to your client project file directly:
+Alternatively, the following section shows what to add to your client project file directly:
```xml
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+
+
-
+
http://localhost:14140/swagger/v1/swagger.json
+ NSwagCSharp
+ ExampleApiClient
+ ExampleApiClient.cs
```
From here, continue from step 3 in the list of steps for Visual Studio.
+# [Kiota](#tab/kiota)
+
+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.
+
+Next, generate client code by running the [command line tool](https://learn.microsoft.com/en-us/openapi/kiota/using#client-generation). For example:
+
+```
+dotnet kiota generate --language CSharp --class-name ExampleApiClient --output ./GeneratedCode --backing-store --exclude-backward-compatible --clean-output --clear-cache --openapi ..\JsonApiDotNetCoreExample\GeneratedSwagger\JsonApiDotNetCoreExample.json
+```
+
+> [!CAUTION]
+> The `--backing-store` switch is needed for JSON:API partial PATCH/POST requests to work correctly.
+
+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
+in place. For a full example, see the [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiKiotaClientExample).
+
+---
+
## Configuration
-### NSwag
+Various switches enable you to tweak the client generation to your needs. See the section below for an overview.
+
+# [NSwag](#tab/nswag)
The `OpenApiReference` element in the project file accepts an `Options` element to pass additional settings to the client generator,
which are listed [here](https://github.com/RicoSuter/NSwag/blob/master/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToCSharpClientCommand.cs).
+A guide with common best practices is available [here](https://stevetalkscode.co.uk/openapireference-commands).
-For example, the next section puts the generated code in a namespace and generates an interface (which is handy for dependency injection):
+For example, the following section puts the generated code in a namespace and generates an interface (which is handy for dependency injection):
```xml
@@ -167,20 +208,47 @@ For example, the next section puts the generated code in a namespace and generat
```
+Likewise, you can enable nullable reference types by adding `/GenerateNullableReferenceTypes:true`, optionally combined with `/GenerateOptionalParameters:true`.
+
+# [Kiota](#tab/kiota)
+
+The available command-line switches for Kiota are described [here](https://learn.microsoft.com/en-us/openapi/kiota/using#client-generation).
+
+At the time of writing, Kiota provides [no official integration](https://github.com/microsoft/kiota/issues/3005) with MSBuild.
+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!
+
+```xml
+
+
+
+
+
+
+
+
+
+```
+
+---
+
## Headers and caching
-To use [ETags for caching](~/usage/caching.md), NSwag needs extra settings to make response headers accessible.
-Specify the following in the `` element of your project file:
+The use of HTTP headers varies per client generator. To use [ETags for caching](~/usage/caching.md), see the notes below.
+
+# [NSwag](#tab/nswag)
+
+NSwag needs extra settings to make response headers accessible. Specify the following in the `` element of your project file:
```
-/GenerateExceptionClasses:false /WrapResponses:true /GenerateResponseClasses:false /ResponseClass:ApiResponse /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client
+/GenerateExceptionClasses:false /WrapResponses:true /GenerateResponseClasses:false /ResponseClass:ApiResponse /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client.NSwag
```
This enables the following code, which is explained below:
```c#
var getResponse = await ApiResponse.TranslateAsync(() => apiClient.GetPersonCollectionAsync(null, null));
-string eTag = getResponse.Headers[HeaderNames.ETag].Single();
+string eTag = getResponse.Headers["ETag"].Single();
Console.WriteLine($"Retrieved {getResponse.Result.Data.Count} people.");
// wait some time...
@@ -197,3 +265,24 @@ The response of the first API call contains both data and an ETag header, which
That ETag gets passed to the second API call. This enables the server to detect if something changed, which optimizes
network usage: no data is sent back, unless is has changed.
If you only want to ask whether data has changed without fetching it, use a HEAD request instead.
+
+# [Kiota](#tab/kiota)
+
+Use `HeadersInspectionHandlerOption` to gain access to response headers. For example:
+
+```c#
+var headerInspector = new HeadersInspectionHandlerOption
+{
+ InspectResponseHeaders = true
+};
+
+var responseDocument = await apiClient.Api.People.GetAsync(configuration => configuration.Options.Add(headerInspector));
+
+string eTag = headerInspector.ResponseHeaders["ETag"].Single();
+```
+
+Due to a [bug in Kiota](https://github.com/microsoft/kiota/issues/4190), a try/catch block is needed additionally to make this work.
+
+For a full example, see the [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiKiotaClientExample).
+
+---
diff --git a/docs/usage/openapi.md b/docs/usage/openapi.md
index 1419a6ba43..e26754d99b 100644
--- a/docs/usage/openapi.md
+++ b/docs/usage/openapi.md
@@ -16,13 +16,10 @@ The package provides an integration with [Swashbuckle](https://github.com/domain
2. Add the integration in your `Program.cs` file.
```c#
- IMvcCoreBuilder mvcCoreBuilder = builder.Services.AddMvcCore();
-
- // Include the mvcBuilder parameter.
- builder.Services.AddJsonApi(mvcBuilder: mvcCoreBuilder);
+ builder.Services.AddJsonApi();
// Configure Swashbuckle for JSON:API.
- builder.Services.AddOpenApi(mvcCoreBuilder);
+ builder.Services.AddOpenApi();
var app = builder.Build();
diff --git a/docs/usage/toc.md b/docs/usage/toc.md
index 6f90725cba..925aa660a2 100644
--- a/docs/usage/toc.md
+++ b/docs/usage/toc.md
@@ -26,7 +26,7 @@
# [Common Pitfalls](common-pitfalls.md)
# [OpenAPI](openapi.md)
-## [Client](openapi-client.md)
+## [Clients](openapi-client.md)
# Extensibility
## [Layer Overview](extensibility/layer-overview.md)
diff --git a/package-versions.props b/package-versions.props
index 0129d2aee2..89a550247d 100644
--- a/package-versions.props
+++ b/package-versions.props
@@ -5,6 +5,7 @@
0.4.1
2.14.1
6.5.0
+ 13.0.3
8.0.*
@@ -17,6 +18,7 @@
6.12.*
2.3.*
2.0.*
+ 1.*
8.0.*
13.20.*
13.0.*
diff --git a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
index 5335a96b42..654abe9a88 100644
--- a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
+++ b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
@@ -16,8 +16,8 @@
-
-
+
+
diff --git a/src/Examples/JsonApiDotNetCoreExample/Program.cs b/src/Examples/JsonApiDotNetCoreExample/Program.cs
index 332235d491..925c2f02e3 100644
--- a/src/Examples/JsonApiDotNetCoreExample/Program.cs
+++ b/src/Examples/JsonApiDotNetCoreExample/Program.cs
@@ -66,8 +66,6 @@ static void ConfigureServices(WebApplicationBuilder builder)
SetDbContextDebugOptions(options);
});
- IMvcCoreBuilder mvcCoreBuilder = builder.Services.AddMvcCore();
-
using (CodeTimingSessionManager.Current.Measure("AddJsonApi()"))
{
builder.Services.AddJsonApi(options =>
@@ -82,12 +80,12 @@ static void ConfigureServices(WebApplicationBuilder builder)
options.IncludeRequestBodyInErrors = true;
options.SerializerOptions.WriteIndented = true;
#endif
- }, discovery => discovery.AddCurrentAssembly(), mvcBuilder: mvcCoreBuilder);
+ }, discovery => discovery.AddCurrentAssembly());
}
using (CodeTimingSessionManager.Current.Measure("AddOpenApi()"))
{
- builder.Services.AddOpenApi(mvcCoreBuilder, options => options.DocumentFilter());
+ builder.Services.AddOpenApi(options => options.DocumentFilter());
}
}
diff --git a/src/Examples/JsonApiDotNetCoreExampleClient/Program.cs b/src/Examples/JsonApiDotNetCoreExampleClient/Program.cs
deleted file mode 100644
index 7f3926f00c..0000000000
--- a/src/Examples/JsonApiDotNetCoreExampleClient/Program.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System.Net;
-using JsonApiDotNetCore.OpenApi.Client;
-using JsonApiDotNetCoreExampleClient;
-using Microsoft.Net.Http.Headers;
-
-#if DEBUG
-using var httpClient = new HttpClient(new ColoredConsoleLogDelegatingHandler
-{
- InnerHandler = new HttpClientHandler()
-});
-#else
-using var httpClient = new HttpClient();
-#endif
-
-var apiClient = new ExampleApiClient(httpClient);
-
-ApiResponse getResponse1 = await GetPersonCollectionAsync(apiClient, null);
-ApiResponse getResponse2 = await GetPersonCollectionAsync(apiClient, getResponse1.Headers[HeaderNames.ETag].First());
-
-if (getResponse2 is { StatusCode: (int)HttpStatusCode.NotModified, Result: null })
-{
- Console.WriteLine("The HTTP response hasn't changed, so no response body was returned.");
-}
-
-foreach (PersonDataInResponse person in getResponse1.Result!.Data)
-{
- PrintPerson(person, getResponse1.Result.Included);
-}
-
-var patchRequest = new PersonPatchRequestDocument
-{
- Data = new PersonDataInPatchRequest
- {
- Id = "1",
- Attributes = new PersonAttributesInPatchRequest
- {
- LastName = "Doe"
- }
- }
-};
-
-// This line results in sending "firstName: null" instead of omitting it.
-using (apiClient.WithPartialAttributeSerialization(patchRequest, person => person.FirstName))
-{
- // Workaround for https://github.com/RicoSuter/NSwag/issues/2499.
- await ApiResponse.TranslateAsync(() => apiClient.PatchPersonAsync(patchRequest.Data.Id, null, patchRequest));
-}
-
-Console.WriteLine("Press any key to close.");
-Console.ReadKey();
-
-static Task> GetPersonCollectionAsync(ExampleApiClient apiClient, string? ifNoneMatch)
-{
- return ApiResponse.TranslateAsync(() => apiClient.GetPersonCollectionAsync(new Dictionary
- {
- ["filter"] = "has(assignedTodoItems)",
- ["sort"] = "-lastName",
- ["page[size]"] = "5",
- ["include"] = "assignedTodoItems.tags"
- }, ifNoneMatch));
-}
-
-static void PrintPerson(PersonDataInResponse person, ICollection includes)
-{
- ToManyTodoItemInResponse assignedTodoItems = person.Relationships.AssignedTodoItems;
-
- Console.WriteLine($"Found person {person.Id}: {person.Attributes.DisplayName} with {assignedTodoItems.Data.Count} assigned todo-items:");
-
- PrintRelatedTodoItems(assignedTodoItems.Data, includes);
-}
-
-static void PrintRelatedTodoItems(IEnumerable todoItemIdentifiers, ICollection includes)
-{
- foreach (TodoItemIdentifier todoItemIdentifier in todoItemIdentifiers)
- {
- TodoItemDataInResponse includedTodoItem = includes.OfType().Single(include => include.Id == todoItemIdentifier.Id);
- Console.WriteLine($" TodoItem {includedTodoItem.Id}: {includedTodoItem.Attributes.Description}");
-
- PrintRelatedTags(includedTodoItem.Relationships.Tags.Data, includes);
- }
-}
-
-static void PrintRelatedTags(IEnumerable tagIdentifiers, ICollection includes)
-{
- foreach (TagIdentifier tagIdentifier in tagIdentifiers)
- {
- TagDataInResponse includedTag = includes.OfType().Single(include => include.Id == tagIdentifier.Id);
- Console.WriteLine($" Tag {includedTag.Id}: {includedTag.Attributes.Name}");
- }
-}
diff --git a/src/Examples/JsonApiDotNetCoreExampleClient/ColoredConsoleLogDelegatingHandler.cs b/src/Examples/OpenApiKiotaClientExample/ColoredConsoleLogHttpMessageHandler.cs
similarity index 90%
rename from src/Examples/JsonApiDotNetCoreExampleClient/ColoredConsoleLogDelegatingHandler.cs
rename to src/Examples/OpenApiKiotaClientExample/ColoredConsoleLogHttpMessageHandler.cs
index 88679e112f..e13aff5a4d 100644
--- a/src/Examples/JsonApiDotNetCoreExampleClient/ColoredConsoleLogDelegatingHandler.cs
+++ b/src/Examples/OpenApiKiotaClientExample/ColoredConsoleLogHttpMessageHandler.cs
@@ -1,24 +1,28 @@
using JetBrains.Annotations;
-namespace JsonApiDotNetCoreExampleClient;
+namespace OpenApiKiotaClientExample;
///
/// Writes incoming and outgoing HTTP messages to the console.
///
-[UsedImplicitly]
-internal sealed class ColoredConsoleLogDelegatingHandler : DelegatingHandler
+internal sealed class ColoredConsoleLogHttpMessageHandler : DelegatingHandler
{
protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
+#if DEBUG
await LogRequestAsync(request, cancellationToken);
+#endif
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
+#if DEBUG
await LogResponseAsync(response, cancellationToken);
+#endif
return response;
}
+ [UsedImplicitly]
private static async Task LogRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
using var _ = new ConsoleColorScope(ConsoleColor.Green);
@@ -33,6 +37,7 @@ private static async Task LogRequestAsync(HttpRequestMessage request, Cancellati
}
}
+ [UsedImplicitly]
private static async Task LogResponseAsync(HttpResponseMessage response, CancellationToken cancellationToken)
{
using var _ = new ConsoleColorScope(ConsoleColor.Cyan);
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/ApiRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/ApiRequestBuilder.cs
new file mode 100644
index 0000000000..f67774090a
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/ApiRequestBuilder.cs
@@ -0,0 +1,43 @@
+//
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Api.People;
+using OpenApiKiotaClientExample.GeneratedCode.Api.Tags;
+using OpenApiKiotaClientExample.GeneratedCode.Api.TodoItems;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api {
+ ///
+ /// Builds and executes requests for operations under \api
+ ///
+ public class ApiRequestBuilder : BaseRequestBuilder {
+ /// The people property
+ public PeopleRequestBuilder People { get =>
+ new PeopleRequestBuilder(PathParameters, RequestAdapter);
+ }
+ /// The tags property
+ public TagsRequestBuilder Tags { get =>
+ new TagsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ /// The todoItems property
+ public TodoItemsRequestBuilder TodoItems { get =>
+ new TodoItemsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ ///
+ /// Instantiates a new ApiRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public ApiRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api", pathParameters) {
+ }
+ ///
+ /// Instantiates a new ApiRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public ApiRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api", rawUrl) {
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/AssignedTodoItems/AssignedTodoItemsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/AssignedTodoItems/AssignedTodoItemsRequestBuilder.cs
new file mode 100644
index 0000000000..5773981c9f
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/AssignedTodoItems/AssignedTodoItemsRequestBuilder.cs
@@ -0,0 +1,133 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.AssignedTodoItems {
+ ///
+ /// Builds and executes requests for operations under \api\people\{id}\assignedTodoItems
+ ///
+ public class AssignedTodoItemsRequestBuilder : BaseRequestBuilder {
+ ///
+ /// Instantiates a new AssignedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public AssignedTodoItemsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/assignedTodoItems{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new AssignedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public AssignedTodoItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/assignedTodoItems{?query*}", rawUrl) {
+ }
+ ///
+ /// Retrieves the related todoItems of an individual person's assignedTodoItems relationship.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TodoItemCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves the related todoItems of an individual person's assignedTodoItems relationship.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public AssignedTodoItemsRequestBuilder WithUrl(string rawUrl) {
+ return new AssignedTodoItemsRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves the related todoItems of an individual person's assignedTodoItems relationship.
+ ///
+ public class AssignedTodoItemsRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class AssignedTodoItemsRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/OwnedTodoItems/OwnedTodoItemsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/OwnedTodoItems/OwnedTodoItemsRequestBuilder.cs
new file mode 100644
index 0000000000..d13bb455d0
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/OwnedTodoItems/OwnedTodoItemsRequestBuilder.cs
@@ -0,0 +1,133 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.OwnedTodoItems {
+ ///
+ /// Builds and executes requests for operations under \api\people\{id}\ownedTodoItems
+ ///
+ public class OwnedTodoItemsRequestBuilder : BaseRequestBuilder {
+ ///
+ /// Instantiates a new OwnedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public OwnedTodoItemsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/ownedTodoItems{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new OwnedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public OwnedTodoItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/ownedTodoItems{?query*}", rawUrl) {
+ }
+ ///
+ /// Retrieves the related todoItems of an individual person's ownedTodoItems relationship.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TodoItemCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves the related todoItems of an individual person's ownedTodoItems relationship.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public OwnedTodoItemsRequestBuilder WithUrl(string rawUrl) {
+ return new OwnedTodoItemsRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves the related todoItems of an individual person's ownedTodoItems relationship.
+ ///
+ public class OwnedTodoItemsRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class OwnedTodoItemsRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/PeopleItemRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/PeopleItemRequestBuilder.cs
new file mode 100644
index 0000000000..27ab0fb180
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/PeopleItemRequestBuilder.cs
@@ -0,0 +1,239 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.AssignedTodoItems;
+using OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.OwnedTodoItems;
+using OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.Relationships;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.People.Item {
+ ///
+ /// Builds and executes requests for operations under \api\people\{id}
+ ///
+ public class PeopleItemRequestBuilder : BaseRequestBuilder {
+ /// The assignedTodoItems property
+ public AssignedTodoItemsRequestBuilder AssignedTodoItems { get =>
+ new AssignedTodoItemsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ /// The ownedTodoItems property
+ public OwnedTodoItemsRequestBuilder OwnedTodoItems { get =>
+ new OwnedTodoItemsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ /// The relationships property
+ public RelationshipsRequestBuilder Relationships { get =>
+ new RelationshipsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ ///
+ /// Instantiates a new PeopleItemRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public PeopleItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new PeopleItemRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public PeopleItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}{?query*}", rawUrl) {
+ }
+ ///
+ /// Deletes an existing person by its identifier.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task DeleteAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task DeleteAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToDeleteRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves an individual person by its identifier.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, PersonPrimaryResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Updates an existing person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PatchAsync(PersonPatchRequestDocument body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PatchAsync(PersonPatchRequestDocument body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPatchRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"422", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, PersonPrimaryResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Deletes an existing person by its identifier.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToDeleteRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToDeleteRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.DELETE, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Retrieves an individual person by its identifier.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Updates an existing person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPatchRequestInformation(PersonPatchRequestDocument body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPatchRequestInformation(PersonPatchRequestDocument body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.PATCH, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public PeopleItemRequestBuilder WithUrl(string rawUrl) {
+ return new PeopleItemRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves an individual person by its identifier.
+ ///
+ public class PeopleItemRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class PeopleItemRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Updates an existing person.
+ ///
+ public class PeopleItemRequestBuilderPatchQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/AssignedTodoItems/AssignedTodoItemsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/AssignedTodoItems/AssignedTodoItemsRequestBuilder.cs
new file mode 100644
index 0000000000..bcf5b07d9c
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/AssignedTodoItems/AssignedTodoItemsRequestBuilder.cs
@@ -0,0 +1,256 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.Relationships.AssignedTodoItems {
+ ///
+ /// Builds and executes requests for operations under \api\people\{id}\relationships\assignedTodoItems
+ ///
+ public class AssignedTodoItemsRequestBuilder : BaseRequestBuilder {
+ ///
+ /// Instantiates a new AssignedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public AssignedTodoItemsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/relationships/assignedTodoItems{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new AssignedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public AssignedTodoItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/relationships/assignedTodoItems{?query*}", rawUrl) {
+ }
+ ///
+ /// Removes existing todoItems from the assignedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task DeleteAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task DeleteAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToDeleteRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual person's assignedTodoItems relationship.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TodoItemIdentifierCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Assigns existing todoItems to the assignedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PatchAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PatchAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPatchRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Adds existing todoItems to the assignedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PostAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PostAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPostRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Removes existing todoItems from the assignedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToDeleteRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToDeleteRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.DELETE, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual person's assignedTodoItems relationship.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Assigns existing todoItems to the assignedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPatchRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPatchRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.PATCH, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Adds existing todoItems to the assignedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPostRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPostRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.POST, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public AssignedTodoItemsRequestBuilder WithUrl(string rawUrl) {
+ return new AssignedTodoItemsRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual person's assignedTodoItems relationship.
+ ///
+ public class AssignedTodoItemsRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class AssignedTodoItemsRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/OwnedTodoItems/OwnedTodoItemsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/OwnedTodoItems/OwnedTodoItemsRequestBuilder.cs
new file mode 100644
index 0000000000..80c5a9bc9b
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/OwnedTodoItems/OwnedTodoItemsRequestBuilder.cs
@@ -0,0 +1,256 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.Relationships.OwnedTodoItems {
+ ///
+ /// Builds and executes requests for operations under \api\people\{id}\relationships\ownedTodoItems
+ ///
+ public class OwnedTodoItemsRequestBuilder : BaseRequestBuilder {
+ ///
+ /// Instantiates a new OwnedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public OwnedTodoItemsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/relationships/ownedTodoItems{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new OwnedTodoItemsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public OwnedTodoItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/relationships/ownedTodoItems{?query*}", rawUrl) {
+ }
+ ///
+ /// Removes existing todoItems from the ownedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task DeleteAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task DeleteAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToDeleteRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual person's ownedTodoItems relationship.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TodoItemIdentifierCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Assigns existing todoItems to the ownedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PatchAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PatchAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPatchRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Adds existing todoItems to the ownedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PostAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PostAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPostRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Removes existing todoItems from the ownedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToDeleteRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToDeleteRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.DELETE, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual person's ownedTodoItems relationship.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Assigns existing todoItems to the ownedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPatchRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPatchRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.PATCH, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Adds existing todoItems to the ownedTodoItems relationship of an individual person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPostRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPostRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.POST, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public OwnedTodoItemsRequestBuilder WithUrl(string rawUrl) {
+ return new OwnedTodoItemsRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual person's ownedTodoItems relationship.
+ ///
+ public class OwnedTodoItemsRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class OwnedTodoItemsRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/RelationshipsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/RelationshipsRequestBuilder.cs
new file mode 100644
index 0000000000..f1adfee806
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/Item/Relationships/RelationshipsRequestBuilder.cs
@@ -0,0 +1,38 @@
+//
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.Relationships.AssignedTodoItems;
+using OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.Relationships.OwnedTodoItems;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.People.Item.Relationships {
+ ///
+ /// Builds and executes requests for operations under \api\people\{id}\relationships
+ ///
+ public class RelationshipsRequestBuilder : BaseRequestBuilder {
+ /// The assignedTodoItems property
+ public AssignedTodoItemsRequestBuilder AssignedTodoItems { get =>
+ new AssignedTodoItemsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ /// The ownedTodoItems property
+ public OwnedTodoItemsRequestBuilder OwnedTodoItems { get =>
+ new OwnedTodoItemsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ ///
+ /// Instantiates a new RelationshipsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public RelationshipsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/relationships", pathParameters) {
+ }
+ ///
+ /// Instantiates a new RelationshipsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public RelationshipsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people/{id}/relationships", rawUrl) {
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/PeopleRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/PeopleRequestBuilder.cs
new file mode 100644
index 0000000000..7ba6f0a5c0
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/People/PeopleRequestBuilder.cs
@@ -0,0 +1,197 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Api.People.Item;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.People {
+ ///
+ /// Builds and executes requests for operations under \api\people
+ ///
+ public class PeopleRequestBuilder : BaseRequestBuilder {
+ /// Gets an item from the OpenApiKiotaClientExample.GeneratedCode.api.people.item collection
+ /// The identifier of the person to retrieve.
+ public PeopleItemRequestBuilder this[string position] { get {
+ var urlTplParams = new Dictionary(PathParameters);
+ urlTplParams.Add("id", position);
+ return new PeopleItemRequestBuilder(urlTplParams, RequestAdapter);
+ } }
+ ///
+ /// Instantiates a new PeopleRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public PeopleRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new PeopleRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public PeopleRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/people{?query*}", rawUrl) {
+ }
+ ///
+ /// Retrieves a collection of people.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, PersonCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Creates a new person.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PostAsync(PersonPostRequestDocument body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PostAsync(PersonPostRequestDocument body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPostRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"403", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"422", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, PersonPrimaryResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves a collection of people.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Creates a new person.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPostRequestInformation(PersonPostRequestDocument body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPostRequestInformation(PersonPostRequestDocument body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.POST, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public PeopleRequestBuilder WithUrl(string rawUrl) {
+ return new PeopleRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves a collection of people.
+ ///
+ public class PeopleRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class PeopleRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Creates a new person.
+ ///
+ public class PeopleRequestBuilderPostQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/Relationships/RelationshipsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/Relationships/RelationshipsRequestBuilder.cs
new file mode 100644
index 0000000000..d7a94e21fc
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/Relationships/RelationshipsRequestBuilder.cs
@@ -0,0 +1,33 @@
+//
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item.Relationships.TodoItems;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item.Relationships {
+ ///
+ /// Builds and executes requests for operations under \api\tags\{id}\relationships
+ ///
+ public class RelationshipsRequestBuilder : BaseRequestBuilder {
+ /// The todoItems property
+ public TodoItemsRequestBuilder TodoItems { get =>
+ new TodoItemsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ ///
+ /// Instantiates a new RelationshipsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public RelationshipsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}/relationships", pathParameters) {
+ }
+ ///
+ /// Instantiates a new RelationshipsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public RelationshipsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}/relationships", rawUrl) {
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/Relationships/TodoItems/TodoItemsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/Relationships/TodoItems/TodoItemsRequestBuilder.cs
new file mode 100644
index 0000000000..aa828bb1ac
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/Relationships/TodoItems/TodoItemsRequestBuilder.cs
@@ -0,0 +1,256 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item.Relationships.TodoItems {
+ ///
+ /// Builds and executes requests for operations under \api\tags\{id}\relationships\todoItems
+ ///
+ public class TodoItemsRequestBuilder : BaseRequestBuilder {
+ ///
+ /// Instantiates a new TodoItemsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public TodoItemsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}/relationships/todoItems{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new TodoItemsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public TodoItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}/relationships/todoItems{?query*}", rawUrl) {
+ }
+ ///
+ /// Removes existing todoItems from the todoItems relationship of an individual tag.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task DeleteAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task DeleteAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToDeleteRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual tag's todoItems relationship.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TodoItemIdentifierCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Assigns existing todoItems to the todoItems relationship of an individual tag.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PatchAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PatchAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPatchRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Adds existing todoItems to the todoItems relationship of an individual tag.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PostAsync(ToManyTodoItemInRequest body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PostAsync(ToManyTodoItemInRequest body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPostRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Removes existing todoItems from the todoItems relationship of an individual tag.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToDeleteRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToDeleteRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.DELETE, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual tag's todoItems relationship.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Assigns existing todoItems to the todoItems relationship of an individual tag.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPatchRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPatchRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.PATCH, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Adds existing todoItems to the todoItems relationship of an individual tag.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPostRequestInformation(ToManyTodoItemInRequest body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPostRequestInformation(ToManyTodoItemInRequest body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.POST, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public TodoItemsRequestBuilder WithUrl(string rawUrl) {
+ return new TodoItemsRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves the related todoItem identities of an individual tag's todoItems relationship.
+ ///
+ public class TodoItemsRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class TodoItemsRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/TagsItemRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/TagsItemRequestBuilder.cs
new file mode 100644
index 0000000000..dcd0c130d5
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/TagsItemRequestBuilder.cs
@@ -0,0 +1,234 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item.Relationships;
+using OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item.TodoItems;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item {
+ ///
+ /// Builds and executes requests for operations under \api\tags\{id}
+ ///
+ public class TagsItemRequestBuilder : BaseRequestBuilder {
+ /// The relationships property
+ public RelationshipsRequestBuilder Relationships { get =>
+ new RelationshipsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ /// The todoItems property
+ public TodoItemsRequestBuilder TodoItems { get =>
+ new TodoItemsRequestBuilder(PathParameters, RequestAdapter);
+ }
+ ///
+ /// Instantiates a new TagsItemRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public TagsItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new TagsItemRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public TagsItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}{?query*}", rawUrl) {
+ }
+ ///
+ /// Deletes an existing tag by its identifier.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task DeleteAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task DeleteAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToDeleteRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ await RequestAdapter.SendNoContentAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves an individual tag by its identifier.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TagPrimaryResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Updates an existing tag.
+ ///
+ /// The request body
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task PatchAsync(TagPatchRequestDocument body, Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task PatchAsync(TagPatchRequestDocument body, Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = ToPatchRequestInformation(body, requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"409", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"422", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TagPrimaryResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Deletes an existing tag by its identifier.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToDeleteRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToDeleteRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.DELETE, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Retrieves an individual tag by its identifier.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Updates an existing tag.
+ ///
+ /// The request body
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToPatchRequestInformation(TagPatchRequestDocument body, Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToPatchRequestInformation(TagPatchRequestDocument body, Action> requestConfiguration = default) {
+#endif
+ _ = body ?? throw new ArgumentNullException(nameof(body));
+ var requestInfo = new RequestInformation(Method.PATCH, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ requestInfo.SetContentFromParsable(RequestAdapter, "application/vnd.api+json", body);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public TagsItemRequestBuilder WithUrl(string rawUrl) {
+ return new TagsItemRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves an individual tag by its identifier.
+ ///
+ public class TagsItemRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class TagsItemRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Updates an existing tag.
+ ///
+ public class TagsItemRequestBuilderPatchQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/TodoItems/TodoItemsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/TodoItems/TodoItemsRequestBuilder.cs
new file mode 100644
index 0000000000..918bf06a3c
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/Item/TodoItems/TodoItemsRequestBuilder.cs
@@ -0,0 +1,133 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item.TodoItems {
+ ///
+ /// Builds and executes requests for operations under \api\tags\{id}\todoItems
+ ///
+ public class TodoItemsRequestBuilder : BaseRequestBuilder {
+ ///
+ /// Instantiates a new TodoItemsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public TodoItemsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}/todoItems{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new TodoItemsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public TodoItemsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags/{id}/todoItems{?query*}", rawUrl) {
+ }
+ ///
+ /// Retrieves the related todoItems of an individual tag's todoItems relationship.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ {"404", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync(requestInfo, TodoItemCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task HeadAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task HeadAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToHeadRequestInformation(requestConfiguration);
+ return await RequestAdapter.SendPrimitiveAsync(requestInfo, default, cancellationToken).ConfigureAwait(false);
+ }
+ ///
+ /// Retrieves the related todoItems of an individual tag's todoItems relationship.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ requestInfo.Headers.TryAdd("Accept", "application/vnd.api+json");
+ return requestInfo;
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public RequestInformation ToHeadRequestInformation(Action>? requestConfiguration = default) {
+#nullable restore
+#else
+ public RequestInformation ToHeadRequestInformation(Action> requestConfiguration = default) {
+#endif
+ var requestInfo = new RequestInformation(Method.HEAD, UrlTemplate, PathParameters);
+ requestInfo.Configure(requestConfiguration);
+ return requestInfo;
+ }
+ ///
+ /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored.
+ ///
+ /// The raw URL to use for the request builder.
+ public TodoItemsRequestBuilder WithUrl(string rawUrl) {
+ return new TodoItemsRequestBuilder(rawUrl, RequestAdapter);
+ }
+ ///
+ /// Retrieves the related todoItems of an individual tag's todoItems relationship.
+ ///
+ public class TodoItemsRequestBuilderGetQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ ///
+ /// Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched.
+ ///
+ public class TodoItemsRequestBuilderHeadQueryParameters {
+ /// For syntax, see the documentation for the [`include`](https://www.jsonapi.net/usage/reading/including-relationships.html)/[`filter`](https://www.jsonapi.net/usage/reading/filtering.html)/[`sort`](https://www.jsonapi.net/usage/reading/sorting.html)/[`page`](https://www.jsonapi.net/usage/reading/pagination.html)/[`fields`](https://www.jsonapi.net/usage/reading/sparse-fieldset-selection.html) query string parameters.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ [QueryParameter("query")]
+ public string? Query { get; set; }
+#nullable restore
+#else
+ [QueryParameter("query")]
+ public string Query { get; set; }
+#endif
+ }
+ }
+}
diff --git a/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/TagsRequestBuilder.cs b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/TagsRequestBuilder.cs
new file mode 100644
index 0000000000..9c9d71cde2
--- /dev/null
+++ b/src/Examples/OpenApiKiotaClientExample/GeneratedCode/Api/Tags/TagsRequestBuilder.cs
@@ -0,0 +1,197 @@
+//
+using Microsoft.Kiota.Abstractions.Serialization;
+using Microsoft.Kiota.Abstractions;
+using OpenApiKiotaClientExample.GeneratedCode.Api.Tags.Item;
+using OpenApiKiotaClientExample.GeneratedCode.Models;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+namespace OpenApiKiotaClientExample.GeneratedCode.Api.Tags {
+ ///
+ /// Builds and executes requests for operations under \api\tags
+ ///
+ public class TagsRequestBuilder : BaseRequestBuilder {
+ /// Gets an item from the OpenApiKiotaClientExample.GeneratedCode.api.tags.item collection
+ /// The identifier of the tag to retrieve.
+ public TagsItemRequestBuilder this[string position] { get {
+ var urlTplParams = new Dictionary(PathParameters);
+ urlTplParams.Add("id", position);
+ return new TagsItemRequestBuilder(urlTplParams, RequestAdapter);
+ } }
+ ///
+ /// Instantiates a new TagsRequestBuilder and sets the default values.
+ ///
+ /// Path parameters for the request
+ /// The request adapter to use to execute the requests.
+ public TagsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags{?query*}", pathParameters) {
+ }
+ ///
+ /// Instantiates a new TagsRequestBuilder and sets the default values.
+ ///
+ /// The raw URL to use for the request builder.
+ /// The request adapter to use to execute the requests.
+ public TagsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/api/tags{?query*}", rawUrl) {
+ }
+ ///
+ /// Retrieves a collection of tags.
+ ///
+ /// Cancellation token to use when cancelling requests
+ /// Configuration for the request such as headers, query parameters, and middleware options.
+#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
+#nullable enable
+ public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) {
+#nullable restore
+#else
+ public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) {
+#endif
+ var requestInfo = ToGetRequestInformation(requestConfiguration);
+ var errorMapping = new Dictionary> {
+ {"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
+ };
+ return await RequestAdapter.SendAsync