Skip to content

Commit 13c0970

Browse files
committed
fix: missing type for openapi v2 query parameters
Signed-off-by: Vincent Biret <[email protected]>
1 parent 3508988 commit 13c0970

File tree

4 files changed

+66
-45
lines changed

4 files changed

+66
-45
lines changed

src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiEdmTypeSchemaGenerator.cs

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,24 @@ namespace Microsoft.OpenApi.OData.Generator
2222
/// </summary>
2323
internal static class OpenApiEdmTypeSchemaGenerator
2424
{
25+
/// <summary>
26+
/// Create a <see cref="OpenApiSchema"/> for a <see cref="IEdmTypeReference"/> when producing an OpenAPI parameter.
27+
/// </summary>
28+
/// <param name="context">The OData context.</param>
29+
/// <param name="edmTypeReference">The Edm type reference.</param>
30+
/// <param name="document">The Open API document to lookup references.</param>
31+
/// <returns>The created <see cref="OpenApiSchema"/>.</returns>
32+
public static OpenApiSchema CreateEdmTypeSchemaForParameter(this ODataContext context, IEdmTypeReference edmTypeReference, OpenApiDocument document)
33+
=> CreateEdmTypeSchema(context, edmTypeReference, document, true);
2534
/// <summary>
2635
/// Create a <see cref="OpenApiSchema"/> for a <see cref="IEdmTypeReference"/>.
2736
/// </summary>
2837
/// <param name="context">The OData context.</param>
2938
/// <param name="edmTypeReference">The Edm type reference.</param>
3039
/// <param name="document">The Open API document to lookup references.</param>
40+
/// <param name="schemaForParameter">Whether the schema is for a parameter.</param>
3141
/// <returns>The created <see cref="OpenApiSchema"/>.</returns>
32-
public static OpenApiSchema CreateEdmTypeSchema(this ODataContext context, IEdmTypeReference edmTypeReference, OpenApiDocument document)
42+
public static OpenApiSchema CreateEdmTypeSchema(this ODataContext context, IEdmTypeReference edmTypeReference, OpenApiDocument document, bool schemaForParameter = false)
3343
{
3444
Utils.CheckArgumentNull(context, nameof(context));
3545
Utils.CheckArgumentNull(edmTypeReference, nameof(edmTypeReference));
@@ -45,7 +55,7 @@ public static OpenApiSchema CreateEdmTypeSchema(this ODataContext context, IEdmT
4555
OpenApiSchema schema;
4656
schema = typeRef.TypeKind() == EdmTypeKind.Complex || typeRef.TypeKind() == EdmTypeKind.Entity
4757
? context.CreateStructuredTypeSchema(typeRef.AsStructured(), document, true)
48-
: context.CreateEdmTypeSchema(typeRef, document);
58+
: context.CreateEdmTypeSchema(typeRef, document, schemaForParameter);
4959

5060
return new OpenApiSchema
5161
{
@@ -67,7 +77,7 @@ public static OpenApiSchema CreateEdmTypeSchema(this ODataContext context, IEdmT
6777
// represented as Schema Objects that are JSON References to definitions in the Definitions Object
6878
case EdmTypeKind.Primitive:
6979
IEdmPrimitiveTypeReference primitiveTypeReference = (IEdmPrimitiveTypeReference)edmTypeReference;
70-
return context.CreateSchema(primitiveTypeReference, document);
80+
return context.CreateSchema(primitiveTypeReference, document, schemaForParameter);
7181

7282
case EdmTypeKind.TypeDefinition:
7383
return context.CreateSchema(((IEdmTypeDefinitionReference)edmTypeReference).TypeDefinition().UnderlyingType, document);
@@ -90,14 +100,15 @@ public static OpenApiSchema CreateEdmTypeSchema(this ODataContext context, IEdmT
90100
/// <param name="context">The OData context.</param>
91101
/// <param name="primitiveType">The Edm primitive reference.</param>
92102
/// <param name="document">The Open API document to lookup references.</param>
103+
/// <param name="schemaForParameter">Whether the schema is for a parameter.</param>
93104
/// <returns>The created <see cref="OpenApiSchema"/>.</returns>
94-
public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiveTypeReference primitiveType, OpenApiDocument document)
105+
public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiveTypeReference primitiveType, OpenApiDocument document, bool schemaForParameter = false)
95106
{
96107
Utils.CheckArgumentNull(context, nameof(context));
97108
Utils.CheckArgumentNull(primitiveType, nameof(primitiveType));
98109
Utils.CheckArgumentNull(document, nameof(document));
99110

100-
OpenApiSchema schema = context.CreateSchema(primitiveType.PrimitiveDefinition(), document);
111+
OpenApiSchema schema = context.CreateSchema(primitiveType.PrimitiveDefinition(), document, schemaForParameter);
101112
if (schema != null)
102113
{
103114
switch(primitiveType.PrimitiveKind())
@@ -151,8 +162,9 @@ public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiv
151162
/// <param name="context">The OData context.</param>
152163
/// <param name="primitiveType">The Edm primitive type.</param>
153164
/// <param name="document">The Open API document to lookup references.</param>
165+
/// <param name="schemaForParameter">Whether the schema is for a parameter.</param>
154166
/// <returns>The created <see cref="OpenApiSchema"/>.</returns>
155-
public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiveType primitiveType, OpenApiDocument document)
167+
public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiveType primitiveType, OpenApiDocument document, bool schemaForParameter = false)
156168
{
157169
Utils.CheckArgumentNull(context, nameof(context));
158170
Utils.CheckArgumentNull(primitiveType, nameof(primitiveType));
@@ -166,6 +178,9 @@ public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiv
166178
AnyOf = null
167179
};
168180

181+
var emitIEEECompatibleTypes = context.Settings.IEEE754Compatible && (context.Settings.OpenApiSpecVersion >= OpenApiSpecVersion.OpenApi3_0 || !schemaForParameter);
182+
var emitV2CompatibleParameterTypes = context.Settings.OpenApiSpecVersion == OpenApiSpecVersion.OpenApi2_0 && schemaForParameter;
183+
169184
switch (primitiveType.PrimitiveKind)
170185
{
171186
case EdmPrimitiveTypeKind.Binary: // binary
@@ -185,36 +200,42 @@ public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiv
185200
schema.Format = "date-time";
186201
schema.Pattern = "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$";
187202
break;
188-
case EdmPrimitiveTypeKind.Decimal: // decimal
189-
if (context.Settings.IEEE754Compatible)
190-
{
191-
schema.OneOf = new List<OpenApiSchema>
192-
{
193-
new OpenApiSchema { Type = JsonSchemaType.Number, Format = Constants.DecimalFormat, Nullable = true },
194-
new OpenApiSchema { Type = JsonSchemaType.String, Nullable = true },
195-
};
196-
}
197-
else
198-
{
203+
case EdmPrimitiveTypeKind.Decimal when emitIEEECompatibleTypes: // decimal
204+
schema.OneOf =
205+
[
206+
new OpenApiSchema { Type = JsonSchemaType.Number, Format = Constants.DecimalFormat, Nullable = true },
207+
new OpenApiSchema { Type = JsonSchemaType.String, Nullable = true },
208+
];
209+
break;
210+
case EdmPrimitiveTypeKind.Decimal when !emitIEEECompatibleTypes: // decimal
199211
schema.Type = JsonSchemaType.Number;
200212
schema.Format = Constants.DecimalFormat;
201-
}
202213
break;
203-
case EdmPrimitiveTypeKind.Double: // double
204-
schema.OneOf = new List<OpenApiSchema>
205-
{
214+
case EdmPrimitiveTypeKind.Double when emitV2CompatibleParameterTypes: // double
215+
schema.Type = JsonSchemaType.Number;
216+
schema.Format = "double";
217+
schema.Nullable = true;
218+
break;
219+
case EdmPrimitiveTypeKind.Double when !emitV2CompatibleParameterTypes: // double
220+
schema.OneOf =
221+
[
206222
new OpenApiSchema { Type = JsonSchemaType.Number, Format = "double", Nullable = true },
207223
new OpenApiSchema { Type = JsonSchemaType.String, Nullable = true },
208224
new OpenApiSchemaReference(Constants.ReferenceNumericName, document)
209-
};
225+
];
210226
break;
211-
case EdmPrimitiveTypeKind.Single: // single
212-
schema.OneOf = new List<OpenApiSchema>
213-
{
227+
case EdmPrimitiveTypeKind.Single when emitV2CompatibleParameterTypes: // single
228+
schema.Type = JsonSchemaType.Number;
229+
schema.Format = "float";
230+
schema.Nullable = true;
231+
break;
232+
case EdmPrimitiveTypeKind.Single when !emitV2CompatibleParameterTypes: // single
233+
schema.OneOf =
234+
[
214235
new OpenApiSchema { Type = JsonSchemaType.Number, Format = "float", Nullable = true },
215236
new OpenApiSchema { Type = JsonSchemaType.String, Nullable = true },
216237
new OpenApiSchemaReference(Constants.ReferenceNumericName, document)
217-
};
238+
];
218239
break;
219240
case EdmPrimitiveTypeKind.Guid: // guid
220241
schema.Type = JsonSchemaType.String;
@@ -233,20 +254,16 @@ public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiv
233254
schema.Minimum = Int32.MinValue; // -2147483648
234255
schema.Maximum = Int32.MaxValue; // 2147483647
235256
break;
236-
case EdmPrimitiveTypeKind.Int64:
237-
if (context.Settings.IEEE754Compatible)
238-
{
239-
schema.OneOf = new List<OpenApiSchema>
240-
{
241-
new OpenApiSchema { Type = JsonSchemaType.Number, Format = Constants.Int64Format, Nullable = true },
242-
new OpenApiSchema { Type = JsonSchemaType.String, Nullable = true }
243-
};
244-
}
245-
else
246-
{
247-
schema.Type = JsonSchemaType.Number;
248-
schema.Format = Constants.Int64Format;
249-
}
257+
case EdmPrimitiveTypeKind.Int64 when emitIEEECompatibleTypes:
258+
schema.OneOf =
259+
[
260+
new OpenApiSchema { Type = JsonSchemaType.Number, Format = Constants.Int64Format, Nullable = true },
261+
new OpenApiSchema { Type = JsonSchemaType.String, Nullable = true }
262+
];
263+
break;
264+
case EdmPrimitiveTypeKind.Int64 when !emitIEEECompatibleTypes:
265+
schema.Type = JsonSchemaType.Number;
266+
schema.Format = Constants.Int64Format;
250267
break;
251268
case EdmPrimitiveTypeKind.SByte:
252269
schema.Type = JsonSchemaType.Number;

src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiParameterGenerator.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public static IList<OpenApiParameter> CreateParameters(this ODataContext context
133133
Name = parameterNameMapping == null ? edmParameter.Name : parameterNameMapping[edmParameter.Name],
134134
In = isOptionalParameter ? ParameterLocation.Query : ParameterLocation.Path,
135135
Required = !isOptionalParameter,
136-
Schema = context.CreateEdmTypeSchema(edmParameter.Type, document)
136+
Schema = context.CreateEdmTypeSchemaForParameter(edmParameter.Type, document)
137137
};
138138
}
139139

@@ -191,7 +191,7 @@ public static IList<OpenApiParameter> CreateKeyParameters(this ODataContext cont
191191
In = ParameterLocation.Path,
192192
Required = true,
193193
Description = $"The unique identifier of {entityType.Name}",
194-
Schema = context.CreateEdmTypeSchema(keys[0].Type, document)
194+
Schema = context.CreateEdmTypeSchemaForParameter(keys[0].Type, document)
195195
};
196196

197197
parameter.Extensions.Add(Constants.xMsKeyType, new OpenApiAny(entityType.Name));
@@ -210,7 +210,7 @@ public static IList<OpenApiParameter> CreateKeyParameters(this ODataContext cont
210210
In = ParameterLocation.Path,
211211
Required = true,
212212
Description = $"Property in multi-part unique identifier of {entityType.Name}",
213-
Schema = context.CreateEdmTypeSchema(keyProperty.Type, document)
213+
Schema = context.CreateEdmTypeSchemaForParameter(keyProperty.Type, document)
214214
};
215215

216216
if (keySegment.KeyMappings != null)
@@ -254,7 +254,7 @@ private static IList<OpenApiParameter> CreateAlternateKeyParameters(ODataContext
254254
Name = alternateKey.First().Key,
255255
In = ParameterLocation.Path,
256256
Description = $"Alternate key of {entityType.Name}",
257-
Schema = context.CreateEdmTypeSchema(alternateKey.First().Value.Type, document),
257+
Schema = context.CreateEdmTypeSchemaForParameter(alternateKey.First().Value.Type, document),
258258
Required = true
259259
}
260260
);
@@ -272,7 +272,7 @@ private static IList<OpenApiParameter> CreateAlternateKeyParameters(ODataContext
272272
Name = compositekey.Key,
273273
In = ParameterLocation.Path,
274274
Description = $"Property in multi-part alternate key of {entityType.Name}",
275-
Schema = context.CreateEdmTypeSchema(compositekey.Value.Type, document),
275+
Schema = context.CreateEdmTypeSchemaForParameter(compositekey.Value.Type, document),
276276
Required = true
277277
}
278278
);

test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,12 +1244,14 @@
12441244
"in": "path",
12451245
"name": "lat",
12461246
"required": true,
1247+
"type": "number",
12471248
"format": "double"
12481249
},
12491250
{
12501251
"in": "path",
12511252
"name": "lon",
12521253
"required": true,
1254+
"type": "number",
12531255
"format": "double"
12541256
}
12551257
],

test/Microsoft.OpenAPI.OData.Reader.Tests/Resources/TripService.OpenApi.V2.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,10 +818,12 @@ paths:
818818
- in: path
819819
name: lat
820820
required: true
821+
type: number
821822
format: double
822823
- in: path
823824
name: lon
824825
required: true
826+
type: number
825827
format: double
826828
responses:
827829
'200':

0 commit comments

Comments
 (0)