Skip to content

Commit c6d691d

Browse files
committed
Adjusted docs and minor refactors
1 parent ec2ccaf commit c6d691d

15 files changed

+154
-114
lines changed
+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Client Generator
2+
3+
You can you can generate a client library from an OpenAPI specification that describes a JsonApiDotNetCore application. For clients genearted with using [NSwag](http://stevetalkscode.co.uk/openapireference-commands) we provide an additional package that enables partial write requests.
4+
5+
## Installation
6+
7+
You are required to install the following NuGet packages:
8+
9+
- `JsonApiDotNetCore.OpenApiClient`
10+
- `NSwag.ApiDescription.Client`
11+
- `Microsoft.Extensions.ApiDescription.Cient`
12+
- `NSwag.ApiDescription.Client`
13+
14+
The following examples demonstrate how to install the `JsonApiDotNetCore.OpenApiClient` package.
15+
16+
### CLI
17+
18+
```
19+
dotnet add package JsonApiDotNetCore.OpenApiClient
20+
```
21+
22+
### Visual Studio
23+
24+
```powershell
25+
Install-Package JsonApiDotNetCore.OpenApiClient
26+
```
27+
28+
### *.csproj
29+
30+
```xml
31+
<ItemGroup>
32+
<!-- Be sure to check NuGet for the latest version # -->
33+
<PackageReference Include="JsonApiDotNetCore.OpenApiClient" Version="4.0.0" />
34+
</ItemGroup>
35+
```
36+
37+
38+
## Adding an OpenApiReference
39+
40+
Add a reference to your OpenAPI specification in your project file as demonstrated below.
41+
42+
```xml
43+
<ItemGroup>
44+
<OpenApiReference Include="swagger.json">
45+
<Namespace>ApiConsumer.GeneratedCode</Namespace>
46+
<ClassName>OpenApiClient</ClassName>
47+
<CodeGenerator>NSwagCSharp</CodeGenerator>
48+
<Options>/UseBaseUrl:false /GenerateClientInterfaces:true</Options>
49+
</OpenApiReference>
50+
</ItemGroup>
51+
```
52+
53+
54+
## Usage
55+
56+
The NSwag tooling generates the OpenAPI client during a prebuild step. Once your application is built,
57+
you can instantiate it using the class name as indicated in the project file.
58+
59+
```c#
60+
namespace ApiConsumer
61+
{
62+
class Program
63+
{
64+
static void Main(string[] args)
65+
{
66+
using (HttpClient httpClient = new HttpClient())
67+
{
68+
OpenApiClient openApiClient = new OpenApiClient(httpClient);
69+
70+
// IntelliSense is now available on `openApiClient`!
71+
}
72+
}
73+
}
74+
}
75+
```
76+
77+
Support for partial write requests can be enabled by leveraging the extensibility points of the generated client.
78+
79+
```c#
80+
// Note that this class should be namespace in which NSwag generates the client.
81+
namespace ApiConsumer.GeneratedCode
82+
{
83+
public partial class OpenApiClient : JsonApiClient
84+
{
85+
partial void UpdateJsonSerializerSettings(JsonSerializerSettings settings)
86+
{
87+
SetSerializerSettingsForJsonApi(settings);
88+
}
89+
}
90+
}
91+
```
92+
93+
You can now perform a write request by calling the `RegisterAttributesForRequest` method. Calling this method treats all attributes that contain their default value (<c>null</c> for reference types, <c>0</c> for integers, <c>false</c> for booleans, etc) as omitted unless explicitly listed to include them using the `alwaysIncludedAttributeSelectors` parameter.
94+
95+
```c#
96+
// Program.cs
97+
static void Main(string[] args)
98+
{
99+
using (HttpClient httpClient = new HttpClient())
100+
{
101+
OpenApiClient openApiClient = new OpenApiClient(httpClient);
102+
103+
var requestDocument = new ApiResourcePatchRequestDocument
104+
{
105+
Data = new ApiResourceDataInPatchRequest
106+
{
107+
Id = 543,
108+
Type = ApiResourceResourceType.Airplanes,
109+
Attributes = new ApiResourceAttributesInPatchRequest
110+
{
111+
someNullableAttribute = "Value"
112+
}
113+
}
114+
};
115+
116+
using (apiClient.RegisterAttributesForRequestDocument<ApiResourcePatchRequestDocument, ApiResourceDataInPatchRequest>(requestDocument, apiResource => apiResource.AnotherNullableAttribute)
117+
{
118+
await apiClient.PatchApiResourceAsync(543, requestDocument));
119+
120+
// The request will look like this:
121+
//
122+
// {
123+
// "data": {
124+
// "type": "apiResource",
125+
// "id": "543",
126+
// "attributes": {
127+
// "someNullableAttribute": "Value",
128+
// "anotherNullableAttribute": null,
129+
// }
130+
// }
131+
// }
132+
}
133+
134+
}
135+
}
136+
```
137+

docs/usage/openapi/openapi.md renamed to docs/usage/openapi/openapi-generator.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# OpenAPI
1+
# OpenAPI generator
22

33
You can describe your API with an OpenAPI specification using the [Swashbuckle](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) integration for JsonApiDotNetCore.
44

docs/usage/openapi/openapiclient.md

-79
This file was deleted.

docs/usage/toc.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
# [Caching](caching.md)
2424

2525
# OpenAPI
26-
## [Specification Generator](openapi/openapi.md))
27-
## [Generated Client](openapi/openapiclient.md))
26+
## [Describing Your API](openapi/openapi-generator.md))
27+
## [Generating A Client](openapi/client-generator.md))
2828

2929
# Extensibility
3030
## [Layer Overview](extensibility/layer-overview.md)

src/JsonApiDotNetCore.OpenApi/JsonApiActionDescriptorCollectionProvider.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
5-
using JsonApiDotNetCore.OpenApi.JsonApiMetadata;
65
using JsonApiDotNetCore.Configuration;
76
using JsonApiDotNetCore.Middleware;
7+
using JsonApiDotNetCore.OpenApi.JsonApiMetadata;
88
using Microsoft.AspNetCore.Mvc;
99
using Microsoft.AspNetCore.Mvc.Abstractions;
1010
using Microsoft.AspNetCore.Mvc.Controllers;

src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/JsonApiEndpointMetadataProvider.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
5-
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
6-
using JsonApiDotNetCore.OpenApi.JsonApiObjects.RelationshipData;
75
using JsonApiDotNetCore.Configuration;
86
using JsonApiDotNetCore.Middleware;
7+
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
8+
using JsonApiDotNetCore.OpenApi.JsonApiObjects.RelationshipData;
99
using JsonApiDotNetCore.Resources.Annotations;
1010

1111
namespace JsonApiDotNetCore.OpenApi.JsonApiMetadata

src/JsonApiDotNetCore.OpenApi/JsonApiOperationIdSelector.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using Humanizer;
5+
using JsonApiDotNetCore.Middleware;
56
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
67
using JsonApiDotNetCore.OpenApi.JsonApiObjects.RelationshipData;
7-
using JsonApiDotNetCore.Middleware;
88
using Microsoft.AspNetCore.Mvc;
99
using Microsoft.AspNetCore.Mvc.ApiExplorer;
1010
using Microsoft.AspNetCore.Mvc.Controllers;

src/JsonApiDotNetCore.OpenApi/JsonApiSchemaIdSelector.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using Humanizer;
5+
using JsonApiDotNetCore.Configuration;
56
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
67
using JsonApiDotNetCore.OpenApi.JsonApiObjects.RelationshipData;
78
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
8-
using JsonApiDotNetCore.Configuration;
99

1010
namespace JsonApiDotNetCore.OpenApi
1111
{

src/JsonApiDotNetCore.OpenApi/SwaggerComponents/JsonApiSchemaGenerator.cs

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System;
22
using System.Linq;
33
using System.Reflection;
4+
using JsonApiDotNetCore.Configuration;
45
using JsonApiDotNetCore.OpenApi.JsonApiObjects;
56
using JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents;
67
using JsonApiDotNetCore.OpenApi.JsonApiObjects.RelationshipData;
7-
using JsonApiDotNetCore.Configuration;
88
using Microsoft.OpenApi.Models;
99
using Swashbuckle.AspNetCore.SwaggerGen;
1010

@@ -66,16 +66,9 @@ public OpenApiSchema GenerateSchema(Type type, SchemaRepository schemaRepository
6666
return jsonApiDocumentSchema;
6767
}
6868

69-
OpenApiSchema schema;
70-
71-
if (IsJsonApiResourceDocument(type))
72-
{
73-
schema = GenerateResourceJsonApiDocumentSchema(type);
74-
}
75-
else
76-
{
77-
schema = _defaultSchemaGenerator.GenerateSchema(type, schemaRepository, memberInfo, parameterInfo);
78-
}
69+
OpenApiSchema schema = IsJsonApiResourceDocument(type)
70+
? GenerateResourceJsonApiDocumentSchema(type)
71+
: _defaultSchemaGenerator.GenerateSchema(type, schemaRepository, memberInfo, parameterInfo);
7972

8073
if (IsSingleNonPrimaryDataDocument(type))
8174
{

src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceObjectSchemaGenerator.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Collections.Generic;
3-
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
43
using JsonApiDotNetCore.Configuration;
4+
using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects;
55
using Microsoft.OpenApi.Models;
66
using Newtonsoft.Json.Serialization;
77
using Swashbuckle.AspNetCore.SwaggerGen;

src/JsonApiDotNetCore.OpenApiClient/JsonApiDotNetCore.OpenApiClient.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<PropertyGroup>
99
<PackageTags>jsonapidotnetcore;jsonapi;json:api;dotnet;asp.net;openapi;swagger;client;nswag</PackageTags>
10-
<Description>Contains utility methods to enrich the usability of an OpenAPI gnerated client.</Description>
10+
<Description>Contains utility methods to enrich the usability of an OpenAPI generated client.</Description>
1111
<Authors>json-api-dotnet</Authors>
1212
<PackageProjectUrl>https://www.jsonapi.net/</PackageProjectUrl>
1313
<PackageLicenseExpression>MIT</PackageLicenseExpression>

test/OpenApiTests/ClientLibrary/GeneratedCode/IOpenApiClient.cs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenApiTests.ClientLibrary.GeneratedCode
44
{
5+
// ReSharper disable once MemberCanBeInternal
56
partial interface IOpenApiClient : IJsonApiClient
67
{
78
}

test/OpenApiTests/ClientLibrary/GeneratedCode/OpenApiClient.cs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace OpenApiTests.ClientLibrary.GeneratedCode
55
{
6+
// ReSharper disable once MemberCanBeInternal
67
public partial class OpenApiClient : JsonApiClient
78
{
89
partial void UpdateJsonSerializerSettings(JsonSerializerSettings settings)

test/OpenApiTests/ClientLibrary/ResponseTests.cs

-2
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ public async Task Getting_resource_collection_translates_response()
121121
flight.Meta["docs"].Should().Be(flightMetaValue);
122122

123123
flight.Attributes.Destination.Should().Be(flightDestination);
124-
flight.Attributes.FlightNumber.Should().Be(null);
125124
flight.Attributes.ServicesOnBoard.Should().HaveCount(3);
126125
flight.Attributes.ServicesOnBoard.ElementAt(0).Should().Be(fightServiceOnBoard);
127126
flight.Attributes.ServicesOnBoard.ElementAt(1).Should().Be(string.Empty);
@@ -187,7 +186,6 @@ public async Task Getting_resource_translates_response()
187186
document.Data.Relationships.Should().BeNull();
188187
document.Data.Attributes.DepartsAt.Should().Be(DateTimeOffset.Parse(departsAtInZuluTime));
189188
document.Data.Attributes.ArrivesAt.Should().Be(DateTimeOffset.Parse(arrivesAtWithUtcOffset));
190-
document.Data.Attributes.FlightNumber.Should().BeNull();
191189
document.Data.Attributes.ServicesOnBoard.Should().BeNull();
192190
document.Data.Attributes.Destination.Should().BeNull();
193191
document.Data.Attributes.OperatedBy.Should().Be(default(Airline));

test/OpenApiTests/swagger.json

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
{
32
"openapi": "3.0.1",
43
"info": {
@@ -2446,11 +2445,6 @@
24462445
"maxLength": 40,
24472446
"type": "string"
24482447
},
2449-
"flight-number": {
2450-
"maxLength": 8,
2451-
"type": "string",
2452-
"nullable": true
2453-
},
24542448
"operated-by": {
24552449
"$ref": "#/components/schemas/airline"
24562450
}
@@ -2464,11 +2458,6 @@
24642458
"maxLength": 40,
24652459
"type": "string"
24662460
},
2467-
"flight-number": {
2468-
"maxLength": 8,
2469-
"type": "string",
2470-
"nullable": true
2471-
},
24722461
"departs-at": {
24732462
"type": "string",
24742463
"format": "date-time",
@@ -3016,4 +3005,4 @@
30163005
}
30173006
}
30183007
}
3019-
}
3008+
}

0 commit comments

Comments
 (0)