Skip to content

Commit 338566f

Browse files
authored
Merge pull request #2699 from microsoft/feat/content-interface-to-v2
feat(models): add shared Content interface (#2695)
2 parents ad53c3c + 80e4bbf commit 338566f

File tree

10 files changed

+82
-66
lines changed

10 files changed

+82
-66
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Collections.Generic;
2+
3+
namespace Microsoft.OpenApi;
4+
5+
/// <summary>
6+
/// Describes an element that has content.
7+
/// </summary>
8+
public interface IOpenApiContentElement
9+
{
10+
/// <summary>
11+
/// A map containing descriptions of potential payloads.
12+
/// The key is a media type or media type range and the value describes it.
13+
/// </summary>
14+
IDictionary<string, OpenApiMediaType>? Content { get; set; }
15+
}
16+
17+
/// <summary>
18+
/// Describes an element that has content.
19+
/// </summary>
20+
public interface IOpenApiReadOnlyContentElement
21+
{
22+
/// <summary>
23+
/// A map containing descriptions of potential payloads.
24+
/// The key is a media type or media type range and the value describes it.
25+
/// </summary>
26+
IDictionary<string, OpenApiMediaType>? Content { get; }
27+
}

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Microsoft.OpenApi;
88
/// Defines the base properties for the headers object.
99
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
1010
/// </summary>
11-
public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiHeader>, IOpenApiReferenceable
11+
public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiHeader>, IOpenApiReferenceable, IOpenApiReadOnlyContentElement
1212
{
1313
/// <summary>
1414
/// Determines whether this header is mandatory.
@@ -57,10 +57,4 @@ public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExte
5757
/// Examples of the media type.
5858
/// </summary>
5959
public IDictionary<string, IOpenApiExample>? Examples { get; }
60-
61-
/// <summary>
62-
/// A map containing the representations for the header.
63-
/// </summary>
64-
public IDictionary<string, OpenApiMediaType>? Content { get; }
65-
6660
}

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Microsoft.OpenApi;
77
/// Defines the base properties for the parameter object.
88
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
99
/// </summary>
10-
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiParameter>, IOpenApiReferenceable
10+
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiParameter>, IOpenApiReferenceable, IOpenApiReadOnlyContentElement
1111
{
1212
/// <summary>
1313
/// REQUIRED. The name of the parameter. Parameter names are case sensitive.
@@ -93,15 +93,4 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE
9393
/// Assign <see cref="JsonNullSentinel.JsonNull"/> to use get null as a serialized value.
9494
/// </summary>
9595
public JsonNode? Example { get; }
96-
97-
/// <summary>
98-
/// A map containing the representations for the parameter.
99-
/// The key is the media type and the value describes it.
100-
/// The map MUST only contain one entry.
101-
/// For more complex scenarios, the content property can define the media type and schema of the parameter.
102-
/// A parameter MUST contain either a schema property, or a content property, but not both.
103-
/// When example or examples are provided in conjunction with the schema object,
104-
/// the example MUST follow the prescribed serialization strategy for the parameter.
105-
/// </summary>
106-
public IDictionary<string, OpenApiMediaType>? Content { get; }
10796
}

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,13 @@ namespace Microsoft.OpenApi;
66
/// Defines the base properties for the request body object.
77
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
88
/// </summary>
9-
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiRequestBody>, IOpenApiReferenceable
9+
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiRequestBody>, IOpenApiReferenceable, IOpenApiReadOnlyContentElement
1010
{
1111
/// <summary>
1212
/// Determines if the request body is required in the request. Defaults to false.
1313
/// </summary>
1414
public bool Required { get; }
1515

16-
/// <summary>
17-
/// REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it.
18-
/// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*
19-
/// </summary>
20-
public IDictionary<string, OpenApiMediaType>? Content { get; }
2116
/// <summary>
2217
/// Converts the request body to a body parameter in preparation for a v2 serialization.
2318
/// </summary>

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,13 @@ namespace Microsoft.OpenApi;
66
/// Defines the base properties for the response object.
77
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
88
/// </summary>
9-
public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiResponse>, IOpenApiReferenceable
9+
public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiResponse>, IOpenApiReferenceable, IOpenApiReadOnlyContentElement
1010
{
1111
/// <summary>
1212
/// Maps a header name to its definition.
1313
/// </summary>
1414
public IDictionary<string, IOpenApiHeader>? Headers { get; }
1515

16-
/// <summary>
17-
/// A map containing descriptions of potential response payloads.
18-
/// The key is a media type or media type range and the value describes it.
19-
/// </summary>
20-
public IDictionary<string, OpenApiMediaType>? Content { get; }
21-
2216
/// <summary>
2317
/// A map of operations links that can be followed from the response.
2418
/// The key of the map is a short name for the link,

src/Microsoft.OpenApi/Models/OpenApiHeader.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Microsoft.OpenApi
1111
/// Header Object.
1212
/// The Header Object follows the structure of the Parameter Object.
1313
/// </summary>
14-
public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible
14+
public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible, IOpenApiContentElement
1515
{
1616
/// <inheritdoc/>
1717
public string? Description { get; set; }
@@ -90,7 +90,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
9090
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
9191
}
9292

93-
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
93+
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
9494
Action<IOpenApiWriter, IOpenApiSerializable> callback)
9595
{
9696
Utils.CheckArgumentNull(writer);
@@ -167,7 +167,8 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
167167
writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false);
168168

169169
// schema
170-
var targetSchema = Schema switch {
170+
var targetSchema = Schema switch
171+
{
171172
OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget,
172173
OpenApiSchema schema => schema,
173174
_ => null,

src/Microsoft.OpenApi/Models/OpenApiParameter.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Microsoft.OpenApi
1111
/// <summary>
1212
/// Parameter Object.
1313
/// </summary>
14-
public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter
14+
public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter, IOpenApiContentElement
1515
{
1616
private bool? _explode;
1717
private ParameterStyle? _style;
@@ -60,7 +60,15 @@ public bool Explode
6060
/// <inheritdoc/>
6161
public JsonNode? Example { get; set; }
6262

63-
/// <inheritdoc/>
63+
/// <summary>
64+
/// A map containing the representations for the parameter.
65+
/// The key is the media type and the value describes it.
66+
/// The map MUST only contain one entry.
67+
/// For more complex scenarios, the content property can define the media type and schema of the parameter.
68+
/// A parameter MUST contain either a schema property, or a content property, but not both.
69+
/// When example or examples are provided in conjunction with the schema object,
70+
/// the example MUST follow the prescribed serialization strategy for the parameter.
71+
/// </summary>
6472
public IDictionary<string, OpenApiMediaType>? Content { get; set; }
6573

6674
/// <inheritdoc/>
@@ -105,7 +113,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
105113
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
106114
}
107115

108-
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
116+
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
109117
Action<IOpenApiWriter, IOpenApiSerializable> callback)
110118
{
111119
Utils.CheckArgumentNull(writer);
@@ -200,7 +208,8 @@ internal virtual void WriteRequestBodySchemaForV2(IOpenApiWriter writer, Diction
200208
// uniqueItems
201209
// enum
202210
// multipleOf
203-
var targetSchema = Schema switch {
211+
var targetSchema = Schema switch
212+
{
204213
OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget,
205214
OpenApiSchema schema => schema,
206215
_ => null,

src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ namespace Microsoft.OpenApi
1010
/// <summary>
1111
/// Request Body Object
1212
/// </summary>
13-
public class OpenApiRequestBody : IOpenApiExtensible, IOpenApiRequestBody
13+
public class OpenApiRequestBody : IOpenApiExtensible, IOpenApiRequestBody, IOpenApiContentElement
1414
{
1515
/// <inheritdoc />
1616
public string? Description { get; set; }
1717

1818
/// <inheritdoc />
1919
public bool Required { get; set; }
2020

21-
/// <inheritdoc />
21+
/// <summary>
22+
/// REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it.
23+
/// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/*
24+
/// </summary>
2225
public IDictionary<string, OpenApiMediaType>? Content { get; set; }
2326

2427
/// <inheritdoc />
@@ -56,7 +59,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
5659
{
5760
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
5861
}
59-
62+
6063
internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
6164
Action<IOpenApiWriter, IOpenApiSerializable> callback)
6265
{
@@ -102,7 +105,7 @@ public IOpenApiParameter ConvertToBodyParameter(IOpenApiWriter writer)
102105
Extensions = Extensions?.ToDictionary(static k => k.Key, static v => v.Value)
103106
};
104107
// Clone extensions so we can remove the x-bodyName extensions from the output V2 model.
105-
if (bodyParameter.Extensions is not null &&
108+
if (bodyParameter.Extensions is not null &&
106109
bodyParameter.Extensions.TryGetValue(OpenApiConstants.BodyName, out var bodyNameExtension) &&
107110
bodyNameExtension is JsonNodeExtension bodyName)
108111
{
@@ -118,7 +121,7 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
118121
if (Content == null || !Content.Any())
119122
yield break;
120123
var properties = Content.First().Value.Schema?.Properties;
121-
if(properties != null)
124+
if (properties != null)
122125
{
123126
foreach (var property in properties)
124127
{
@@ -136,11 +139,11 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
136139
OpenApiSchemaReference => throw new InvalidOperationException("Unresolved reference target"),
137140
_ => throw new InvalidOperationException("Unexpected schema type")
138141
};
139-
142+
140143
updatedSchema.Type = "file".ToJsonSchemaType();
141144
updatedSchema.Format = null;
142145
paramSchema = updatedSchema;
143-
146+
144147
}
145148
yield return new OpenApiFormDataParameter()
146149
{
@@ -151,7 +154,7 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
151154
Required = Content.First().Value.Schema?.Required?.Contains(property.Key) ?? false
152155
};
153156
}
154-
}
157+
}
155158
}
156159

157160
/// <inheritdoc/>

src/Microsoft.OpenApi/Models/OpenApiResponse.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.OpenApi
1010
/// <summary>
1111
/// Response object.
1212
/// </summary>
13-
public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse
13+
public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse, IOpenApiContentElement
1414
{
1515
/// <inheritdoc/>
1616
public string? Description { get; set; }
@@ -61,7 +61,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer)
6161
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
6262
}
6363

64-
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
64+
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
6565
Action<IOpenApiWriter, IOpenApiSerializable> callback)
6666
{
6767
Utils.CheckArgumentNull(writer);
@@ -153,7 +153,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer)
153153
// so remove it from the cloned collection so we don't write it again.
154154
extensionsClone?.Remove(key);
155155
}
156-
}
156+
}
157157
}
158158
}
159159

0 commit comments

Comments
 (0)