From 9027f62dd1c6824fc50bd6967b40b2bd1293e741 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Fri, 16 Jun 2023 16:21:23 +0200 Subject: [PATCH 1/9] For `net7.0` or greater, add `JsonDerivedType` and `JsonPolymorphic` attribute support to `Swashbuckle.AspNetCore.Annotations` --- .../AnnotationsSwaggerGenOptionsExtensions.cs | 37 ++++++++++++++++++- .../SwaggerDiscriminatorAttribute.cs | 3 ++ .../SwaggerSubTypeAttribute.cs | 3 ++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs b/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs index a7829c0b6a..e73a195aba 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json.Serialization; using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.Annotations; @@ -56,8 +57,20 @@ public static void EnableAnnotations(this SwaggerGenOptions options) private static IEnumerable AnnotationsSubTypesSelector(Type type) { +#if NET7_0_OR_GREATER + var jsonDerivedTypeAttributes = type.GetCustomAttributes(false) + .OfType() + .ToArray(); + + if (jsonDerivedTypeAttributes.Any()) + { + return jsonDerivedTypeAttributes.Select(attr => attr.DerivedType); + } +#endif + var subTypeAttributes = type.GetCustomAttributes(false) - .OfType(); + .OfType() + .ToArray(); if (subTypeAttributes.Any()) { @@ -80,6 +93,17 @@ private static IEnumerable AnnotationsSubTypesSelector(Type type) private static string AnnotationsDiscriminatorNameSelector(Type baseType) { +#if NET7_0_OR_GREATER + var jsonPolymorphicAttribute = baseType.GetCustomAttributes(false) + .OfType() + .FirstOrDefault(); + + if (jsonPolymorphicAttribute is not null) + { + return jsonPolymorphicAttribute.TypeDiscriminatorPropertyName; + } +#endif + var discriminatorAttribute = baseType.GetCustomAttributes(false) .OfType() .FirstOrDefault(); @@ -108,6 +132,17 @@ private static string AnnotationsDiscriminatorValueSelector(Type subType) if (subType.BaseType == null) return null; +#if NET7_0_OR_GREATER + var jsonDerivedTypeAttribute = subType.BaseType.GetCustomAttributes(false) + .OfType() + .FirstOrDefault(attr => attr.DerivedType == subType); + + if (jsonDerivedTypeAttribute is not null) + { + return jsonDerivedTypeAttribute.TypeDiscriminator?.ToString(); + } +#endif + var subTypeAttribute = subType.BaseType.GetCustomAttributes(false) .OfType() .FirstOrDefault(attr => attr.SubType == subType); diff --git a/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs b/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs index ef44fef185..c83c8502a9 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs @@ -2,6 +2,9 @@ namespace Swashbuckle.AspNetCore.Annotations { +#if NET7_0_OR_GREATER + [Obsolete("Use JsonPolymorphic attribute instead")] +#endif [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] public class SwaggerDiscriminatorAttribute : Attribute { diff --git a/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs b/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs index 52bd13e6b4..52d7b639cd 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs @@ -2,6 +2,9 @@ namespace Swashbuckle.AspNetCore.Annotations { +#if NET7_0_OR_GREATER + [Obsolete("Use JsonDerivedType attribute instead")] +#endif [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = true)] public class SwaggerSubTypeAttribute : Attribute { From 1e40b73611242672e9def9a6772bea1be4ece72c Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Fri, 16 Jun 2023 16:22:30 +0200 Subject: [PATCH 2/9] Use JsonPolymorphic/JsonDeriveType attributes in NswagClientExample for .NET 7 or greater --- .../NswagClientExample/Controllers/AnimalsController.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs b/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs index 8b59829e33..c5543062c9 100644 --- a/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs +++ b/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs @@ -17,9 +17,15 @@ public void CreateAnimal([Required]Animal animal) } } +#if NET7_0_OR_GREATER + [JsonPolymorphic(TypeDiscriminatorPropertyName = "animalType")] + [JsonDerivedType(typeof(Cat), "Cat")] + [JsonDerivedType(typeof(Dog), "Dog")] +#else [SwaggerDiscriminator("animalType")] [SwaggerSubType(typeof(Cat), DiscriminatorValue = "Cat")] [SwaggerSubType(typeof(Dog), DiscriminatorValue = "Dog")] +#endif public class Animal { public AnimalType AnimalType { get; set; } From dd6ed60b68795fe2b0405901f990959fe76cb3b8 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Fri, 16 Jun 2023 17:09:57 +0200 Subject: [PATCH 3/9] Update inheritance and polymorphism docs --- README.md | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 057d59b784..1989dd19c3 100644 --- a/README.md +++ b/README.md @@ -1165,7 +1165,7 @@ services.AddSwaggerGen(c => }); ``` -_NOTE: If you're using the [Swashbuckle Annotations library](#swashbuckleaspnetcoreannotations), it contains a custom selector that's based on the presence of `SwaggerSubType` attributes on base class definitions. This way, you can use simple attributes to explicitly list the inheritance and/or polymorphism relationships you want to expose. To enable this behavior, check out the [Annotations docs](#list-known-subtypes-for-inheritance-and-polymorphism)._ +_NOTE: If you're using the [Swashbuckle Annotations library](#swashbuckleaspnetcoreannotations), it contains a custom selector that's based on the presence of `JsonDerivedType` (or `SwaggerSubType` for .NET 6 or earlier) attributes on base class definitions. This way, you can use simple attributes to explicitly list the inheritance and/or polymorphism relationships you want to expose. To enable this behavior, check out the [Annotations docs](#list-known-subtypes-for-inheritance-and-polymorphism)._ #### Describing Discriminators #### @@ -1231,7 +1231,7 @@ services.AddSwaggerGen(c => }); ``` -_NOTE: If you're using the [Swashbuckle Annotations library](#swashbuckleaspnetcoreannotations), it contains custom selector functions that are based on the presence of `SwaggerDiscriminator` and `SwaggerSubType` attributes on base class definitions. This way, you can use simple attributes to explicitly provide discriminator metadata. To enable this behavior, check out the [Annotations docs](#enrich-polymorphic-base-classes-with-discriminator-metadata)._ +_NOTE: If you're using the [Swashbuckle Annotations library](#swashbuckleaspnetcoreannotations), it contains custom selector functions that are based on the presence of `JsonPolymorphic` (or `SwaggerDiscriminator` for .NET 6 or earlier) and `JsonDerivedType` (or `SwaggerSubType` for .NET 6 or earlier) attributes on base class definitions. This way, you can use simple attributes to explicitly provide discriminator metadata. To enable this behavior, check out the [Annotations docs](#enrich-polymorphic-base-classes-with-discriminator-metadata)._ ## Swashbuckle.AspNetCore.SwaggerUI ## @@ -1539,6 +1539,15 @@ services.AddSwaggerGen(c => }); // Shape.cs + +// .NET 7 or later +[JsonDerivedType(typeof(Rectangle))] +[JsonDerivedType(typeof(Circle))] +public abstract class Shape +{ +} + +// .NET 6 or earlier [SwaggerSubType(typeof(Rectangle))] [SwaggerSubType(typeof(Circle))] public abstract class Shape @@ -1548,7 +1557,7 @@ public abstract class Shape ### Enrich Polymorphic Base Classes with Discriminator Metadata ### -If you're using annotations to _explicitly_ indicate the "known" subtypes for a polymorphic base type, you can combine the `SwaggerDiscriminatorAttribute` with the `SwaggerSubTypeAttribute` to provide additional metadata about the "discriminator" property, which will then be incorporated into the generated schema definition: +If you're using annotations to _explicitly_ indicate the "known" subtypes for a polymorphic base type, you can combine the `JsonPolymorphicAttribute` with the `JsonDerivedTypeAttribute` to provide additional metadata about the "discriminator" property, which will then be incorporated into the generated schema definition: ```csharp @@ -1559,12 +1568,32 @@ services.AddSwaggerGen(c => }); // Shape.cs + +// .NET 7 or later +[JsonPolymorphic(TypeDiscriminatorPropertyName = "shapeType")] +[JsonDerivedType(typeof(Rectangle), "rectangle")] +[JsonDerivedType(typeof(Circle), "circle")] +public abstract class Shape +{ + // Avoid using a JsonPolymorphicAttribute.TypeDiscriminatorPropertyName + // that conflicts with a property in your type hierarchy. + // Related issue: https://github.com/dotnet/runtime/issues/72170 +} + +// .NET 6 or earlier [SwaggerDiscriminator("shapeType")] [SwaggerSubType(typeof(Rectangle), DiscriminatorValue = "rectangle")] [SwaggerSubType(typeof(Circle), DiscriminatorValue = "circle")] public abstract class Shape { - public ShapeType { get; set; } + public ShapeType ShapeType { get; set; } +} + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum AnimalType +{ + Circle, + Rectangle } ``` From 68000beb5c8085a48800b301f0dc9d02253e8c20 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Fri, 21 Jun 2024 01:47:49 +0200 Subject: [PATCH 4/9] Disable CS0618 warnings to ensure backward compatibility with old inheritance attributes --- .../AnnotationsSwaggerGenOptionsExtensions.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs b/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs index e73a195aba..b92bb60726 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/AnnotationsSwaggerGenOptionsExtensions.cs @@ -68,9 +68,11 @@ private static IEnumerable AnnotationsSubTypesSelector(Type type) } #endif +#pragma warning disable CS0618 // Type or member is obsolete var subTypeAttributes = type.GetCustomAttributes(false) .OfType() .ToArray(); +#pragma warning restore CS0618 // Type or member is obsolete if (subTypeAttributes.Any()) { @@ -104,9 +106,11 @@ private static string AnnotationsDiscriminatorNameSelector(Type baseType) } #endif +#pragma warning disable CS0618 // Type or member is obsolete var discriminatorAttribute = baseType.GetCustomAttributes(false) .OfType() .FirstOrDefault(); +#pragma warning restore CS0618 // Type or member is obsolete if (discriminatorAttribute != null) { @@ -143,9 +147,11 @@ private static string AnnotationsDiscriminatorValueSelector(Type subType) } #endif +#pragma warning disable CS0618 // Type or member is obsolete var subTypeAttribute = subType.BaseType.GetCustomAttributes(false) .OfType() .FirstOrDefault(attr => attr.SubType == subType); +#pragma warning restore CS0618 // Type or member is obsolete if (subTypeAttribute != null) { From 01c08e7a5d2a2d9dcf8d391af8fa718e86e1cd60 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Sun, 1 Sep 2024 23:02:42 +0200 Subject: [PATCH 5/9] Implement code review suggestions: README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1989dd19c3..6892e57102 100644 --- a/README.md +++ b/README.md @@ -1590,7 +1590,7 @@ public abstract class Shape } [JsonConverter(typeof(JsonStringEnumConverter))] -public enum AnimalType +public enum ShapeType { Circle, Rectangle From 2c877ada6ba7a4448b21d0b906b2f5e990a701e1 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Sun, 1 Sep 2024 23:05:27 +0200 Subject: [PATCH 6/9] Implement code review suggestions: remove premature `Obsolete` attributes --- .../SwaggerDiscriminatorAttribute.cs | 5 +---- .../SwaggerSubTypeAttribute.cs | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs b/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs index c83c8502a9..73ffcef63d 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs @@ -2,9 +2,6 @@ namespace Swashbuckle.AspNetCore.Annotations { -#if NET7_0_OR_GREATER - [Obsolete("Use JsonPolymorphic attribute instead")] -#endif [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] public class SwaggerDiscriminatorAttribute : Attribute { @@ -15,4 +12,4 @@ public SwaggerDiscriminatorAttribute(string propertyName) public string PropertyName { get; set; } } -} \ No newline at end of file +} diff --git a/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs b/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs index 52d7b639cd..ea3adf3901 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs @@ -2,9 +2,6 @@ namespace Swashbuckle.AspNetCore.Annotations { -#if NET7_0_OR_GREATER - [Obsolete("Use JsonDerivedType attribute instead")] -#endif [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = true)] public class SwaggerSubTypeAttribute : Attribute { @@ -17,4 +14,4 @@ public SwaggerSubTypeAttribute(Type subType) public string DiscriminatorValue { get; set; } } -} \ No newline at end of file +} From 90b5520e3213d47769984720dd3de84656e4b449 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Sun, 1 Sep 2024 23:37:21 +0200 Subject: [PATCH 7/9] Implement code review suggestions: add dedicated type to test STJ polymorphism --- .../Controllers/AnimalsController.cs | 6 --- .../Controllers/PaymentMethodsController.cs | 37 +++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 test/WebSites/NswagClientExample/Controllers/PaymentMethodsController.cs diff --git a/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs b/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs index c5543062c9..8b59829e33 100644 --- a/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs +++ b/test/WebSites/NswagClientExample/Controllers/AnimalsController.cs @@ -17,15 +17,9 @@ public void CreateAnimal([Required]Animal animal) } } -#if NET7_0_OR_GREATER - [JsonPolymorphic(TypeDiscriminatorPropertyName = "animalType")] - [JsonDerivedType(typeof(Cat), "Cat")] - [JsonDerivedType(typeof(Dog), "Dog")] -#else [SwaggerDiscriminator("animalType")] [SwaggerSubType(typeof(Cat), DiscriminatorValue = "Cat")] [SwaggerSubType(typeof(Dog), DiscriminatorValue = "Dog")] -#endif public class Animal { public AnimalType AnimalType { get; set; } diff --git a/test/WebSites/NswagClientExample/Controllers/PaymentMethodsController.cs b/test/WebSites/NswagClientExample/Controllers/PaymentMethodsController.cs new file mode 100644 index 0000000000..8c29280993 --- /dev/null +++ b/test/WebSites/NswagClientExample/Controllers/PaymentMethodsController.cs @@ -0,0 +1,37 @@ +#if NET7_0_OR_GREATER +using System; +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Mvc; + +namespace NSwagClientExample.Controllers +{ + [ApiController] + [Route("[controller]")] + public class PaymentMethodsController : ControllerBase + { + [HttpPost] + public void AddPaymentMethod([Required]PaymentMethod paymentMethod) + { + throw new NotImplementedException(); + } + } + + [JsonPolymorphic(TypeDiscriminatorPropertyName = "paymentMethod")] + [JsonDerivedType(typeof(CreditCard), "CreditCard")] + [JsonDerivedType(typeof(MobileWallet), "MobileWallet")] + public class PaymentMethod + { + } + + public class CreditCard : PaymentMethod + { + public string CardNumber { get; set; } + } + + public class MobileWallet : PaymentMethod + { + public string WalletId { get; set; } + } +} +#endif From a6d72db96e749cf8086eced81c4794dc116622f7 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Sun, 1 Sep 2024 23:40:52 +0200 Subject: [PATCH 8/9] Remove unnecessary reformatting --- .../SwaggerDiscriminatorAttribute.cs | 2 +- .../SwaggerSubTypeAttribute.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs b/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs index 73ffcef63d..ef44fef185 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/SwaggerDiscriminatorAttribute.cs @@ -12,4 +12,4 @@ public SwaggerDiscriminatorAttribute(string propertyName) public string PropertyName { get; set; } } -} +} \ No newline at end of file diff --git a/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs b/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs index ea3adf3901..52bd13e6b4 100644 --- a/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs +++ b/src/Swashbuckle.AspNetCore.Annotations/SwaggerSubTypeAttribute.cs @@ -14,4 +14,4 @@ public SwaggerSubTypeAttribute(Type subType) public string DiscriminatorValue { get; set; } } -} +} \ No newline at end of file From 6b1b44296f8a4bb769b5c5bf9b66fd2982053cf8 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Mon, 2 Sep 2024 00:06:32 +0200 Subject: [PATCH 9/9] Add failing STJ polymorphism integration tests --- .../SwaggerVerifyIntegrationTest.cs | 1 + ...hbuckle.AspNetCore.IntegrationTests.csproj | 1 + .../NswagClientExample/swagger_net8.0.json | 115 ++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs index ca92a7e86c..e56e5cca4b 100644 --- a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs +++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.cs @@ -19,6 +19,7 @@ public partial class SwaggerVerifyIntegrationTest [InlineData(typeof(GenericControllers.Startup), "/swagger/v1/swagger.json")] [InlineData(typeof(MultipleVersions.Startup), "/swagger/1.0/swagger.json")] [InlineData(typeof(MultipleVersions.Startup), "/swagger/2.0/swagger.json")] + [InlineData(typeof(NSwagClientExample.Startup), "/swagger/v1/swagger.json")] [InlineData(typeof(OAuth2Integration.Startup), "/resource-server/swagger/v1/swagger.json")] [InlineData(typeof(ReDocApp.Startup), "/swagger/v1/swagger.json")] [InlineData(typeof(TestFirst.Startup), "/swagger/v1-generated/openapi.json")] diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj b/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj index 8390f7df37..f5b46eef96 100644 --- a/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj +++ b/test/Swashbuckle.AspNetCore.IntegrationTests/Swashbuckle.AspNetCore.IntegrationTests.csproj @@ -16,6 +16,7 @@ + diff --git a/test/WebSites/NswagClientExample/swagger_net8.0.json b/test/WebSites/NswagClientExample/swagger_net8.0.json index 68e90e3375..9449bc1309 100644 --- a/test/WebSites/NswagClientExample/swagger_net8.0.json +++ b/test/WebSites/NswagClientExample/swagger_net8.0.json @@ -71,6 +71,68 @@ } } } + }, + "/PaymentMethods": { + "post": { + "tags": [ + "PaymentMethods" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/PaymentMethod" + }, + { + "$ref": "#/components/schemas/CreditCard" + }, + { + "$ref": "#/components/schemas/MobileWallet" + } + ] + } + }, + "text/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/PaymentMethod" + }, + { + "$ref": "#/components/schemas/CreditCard" + }, + { + "$ref": "#/components/schemas/MobileWallet" + } + ] + } + }, + "application/*+json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/PaymentMethod" + }, + { + "$ref": "#/components/schemas/CreditCard" + }, + { + "$ref": "#/components/schemas/MobileWallet" + } + ] + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + } + } + } } }, "components": { @@ -118,6 +180,23 @@ } ] }, + "CreditCard": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethod" + }, + { + "type": "object", + "properties": { + "cardNumber": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + ] + }, "Dog": { "allOf": [ { @@ -134,6 +213,42 @@ "additionalProperties": false } ] + }, + "MobileWallet": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethod" + }, + { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + ] + }, + "PaymentMethod": { + "required": [ + "paymentMethod" + ], + "type": "object", + "properties": { + "paymentMethod": { + "type": "string" + } + }, + "additionalProperties": false, + "discriminator": { + "propertyName": "paymentMethod", + "mapping": { + "CreditCard": "#/components/schemas/CreditCard", + "MobileWallet": "#/components/schemas/MobileWallet" + } + } } } }