Skip to content

Commit

Permalink
Merge pull request #1580 from json-api-dotnet/openapi-operations
Browse files Browse the repository at this point in the history
OpenAPI support for Atomic Operations
  • Loading branch information
bkoelman authored Jun 30, 2024
2 parents 1053099 + e9476b8 commit 67924c4
Show file tree
Hide file tree
Showing 1,053 changed files with 68,027 additions and 29,995 deletions.
17 changes: 11 additions & 6 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,36 @@
"version": "2024.1.4",
"commands": [
"jb"
]
],
"rollForward": false
},
"regitlint": {
"version": "6.3.12",
"commands": [
"regitlint"
]
],
"rollForward": false
},
"dotnet-reportgenerator-globaltool": {
"version": "5.3.6",
"commands": [
"reportgenerator"
]
],
"rollForward": false
},
"docfx": {
"version": "2.76.0",
"commands": [
"docfx"
]
],
"rollForward": false
},
"microsoft.openapi.kiota": {
"version": "1.14.0",
"version": "1.15.0",
"commands": [
"kiota"
]
],
"rollForward": false
}
}
}
2 changes: 1 addition & 1 deletion CSharpGuidelinesAnalyzer.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<cSharpGuidelinesAnalyzerSettings>
<setting rule="AV1561" name="MaxParameterCount" value="6" />
<setting rule="AV1561" name="MaxConstructorParameterCount" value="13" />
<setting rule="AV1561" name="MaxConstructorParameterCount" value="15" />
</cSharpGuidelinesAnalyzerSettings>
50 changes: 38 additions & 12 deletions docs/usage/openapi-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The following steps describe how to generate and use a JSON:API client in C#, us
5. Add the following line inside the **OpenApiReference** section in your project file:

```xml
<Options>/GenerateExceptionClasses:false /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client.NSwag</Options>
<Options>/GenerateExceptionClasses:false /GenerateNullableReferenceTypes:true /GenerateOptionalPropertiesAsNullable:true /GenerateOptionalParameters:true /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client.NSwag</Options>
```

6. Add the following glue code to connect our package with your generated code.
Expand Down Expand Up @@ -105,31 +105,32 @@ The following steps describe how to generate and use a JSON:API client in C#, us

foreach (var person in getResponse.Data)
{
Console.WriteLine($"Found person {person.Id}: {person.Attributes.DisplayName}");
Console.WriteLine($"Found person {person.Id}: {person.Attributes!.DisplayName}");
}
```

8. Extend your demo code to send a partial PATCH request with the help of our package:

```c#
var patchRequest = new PersonPatchRequestDocument
var updatePersonRequest = new UpdatePersonRequestDocument
{
Data = new PersonDataInPatchRequest
Data = new DataInUpdatePersonRequest
{
Id = "1",
Attributes = new PersonAttributesInPatchRequest
Attributes = new AttributesInUpdatePersonRequest
{
LastName = "Doe"
}
}
};

// This line results in sending "firstName: null" instead of omitting it.
using (apiClient.WithPartialAttributeSerialization<PersonPatchRequestDocument, PersonAttributesInPatchRequest>(patchRequest,
person => person.FirstName))
using (apiClient.WithPartialAttributeSerialization<UpdatePersonRequestDocument, AttributesInUpdatePersonRequest>(
updatePersonRequest, person => person.FirstName))
{
// Workaround for https://github.com/RicoSuter/NSwag/issues/2499.
await ApiResponse.TranslateAsync(() => apiClient.PatchPersonAsync(patchRequest.Data.Id, null, patchRequest));
await ApiResponse.TranslateAsync(() =>
apiClient.PatchPersonAsync(updatePersonRequest.Data.Id, updatePersonRequest));

// The sent request looks like this:
// {
Expand Down Expand Up @@ -171,6 +172,7 @@ Alternatively, the following section shows what to add to your client project fi
<CodeGenerator>NSwagCSharp</CodeGenerator>
<ClassName>ExampleApiClient</ClassName>
<OutputPath>ExampleApiClient.cs</OutputPath>
<Options>/GenerateExceptionClasses:false /GenerateNullableReferenceTypes:true /GenerateOptionalPropertiesAsNullable:true /GenerateOptionalParameters:true /AdditionalNamespaceUsages:JsonApiDotNetCore.OpenApi.Client.NSwag</Options>
</OpenApiReference>
</ItemGroup>
```
Expand All @@ -184,7 +186,7 @@ To generate your C# client, install the Kiota tool by following the steps at htt
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
dotnet kiota generate --language CSharp --class-name ExampleApiClient --output ./GeneratedCode --backing-store --exclude-backward-compatible --clean-output --clear-cache --openapi http://localhost:14140/swagger/v1/swagger.json
```

> [!CAUTION]
Expand Down Expand Up @@ -216,7 +218,7 @@ For example, the following section puts the generated code in a namespace and ge
</OpenApiReference>
```

Likewise, you can enable nullable reference types by adding `/GenerateNullableReferenceTypes:true`, optionally combined with `/GenerateOptionalParameters:true`.
Likewise, you can enable nullable reference types by adding `/GenerateNullableReferenceTypes:true /GenerateOptionalPropertiesAsNullable:true /GenerateOptionalParameters:true`.

# [Kiota](#tab/kiota)

Expand Down Expand Up @@ -256,9 +258,9 @@ NSwag needs extra settings to make response headers accessible. Specify the foll
This enables the following code, which is explained below:

```c#
var getResponse = await ApiResponse.TranslateAsync(() => apiClient.GetPersonCollectionAsync(null, null));
var getResponse = await ApiResponse.TranslateAsync(() => apiClient.GetPersonCollectionAsync());
string eTag = getResponse.Headers["ETag"].Single();
Console.WriteLine($"Retrieved {getResponse.Result.Data.Count} people.");
Console.WriteLine($"Retrieved {getResponse.Result?.Data.Count ?? 0} people.");

// wait some time...
Expand Down Expand Up @@ -295,3 +297,27 @@ Due to a [bug in Kiota](https://github.com/microsoft/kiota/issues/4190), a try/c
For a full example, see the [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiKiotaClientExample).

---

## Atomic operations

# [NSwag](#tab/nswag)

[Atomic operations](~/usage/writing/bulk-batch-operations.md) are fully supported.
The [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiNSwagClientExample)
demonstrates how to use them. It uses local IDs to:
- Create a new tag
- Create a new person
- Create a new todo-item, tagged with the new tag, and owned by the new person
- Assign the todo-item to the created person

# [Kiota](#tab/kiota)

[Atomic operations](~/usage/writing/bulk-batch-operations.md) are fully supported.
See the [example project](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/openapi/src/Examples/OpenApiKiotaClientExample)
demonstrates how to use them. It uses local IDs to:
- Create a new tag
- Create a new person
- Create a new todo-item, tagged with the new tag, and owned by the new person
- Assign the todo-item to the created person

---
Loading

0 comments on commit 67924c4

Please sign in to comment.