Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,13 @@ private void UpdateEndpointsAndOpenApiDefinitions(

var modelsByName = CreateModelsByNameLookup(models);

_transformer.AddDefinitions(endpoints, models, modelsByName, schema);

// When multiple endpoints share (method, route): a descriptor with a valid document
// wins. If no duplicate produces a valid descriptor, the first one whose document
// failed validation is kept so the route is still registered (the middleware returns
// HTTP 500 on call). Descriptors that fail to construct outright are skipped.
// The chosen descriptors are tracked in a list so registration order is deterministic
// (first appearance of each key in `endpoints`, which is already sorted by name).
// Track the chosen definitions in parallel with the descriptors so the same selection
// feeds both the runtime endpoints and the OpenAPI document generation.
var chosenDefinitions = new List<OpenApiEndpointDefinition>();
var chosenDescriptors = new List<OpenApiEndpointDescriptor>();
var keyToIndex = new Dictionary<(string, string), int>();
var keyHasValid = new HashSet<(string, string)>();
Expand Down Expand Up @@ -208,11 +207,13 @@ private void UpdateEndpointsAndOpenApiDefinitions(
if (keyToIndex.TryGetValue(key, out var existingIndex))
{
// Promote: an earlier invalid descriptor is being replaced by a valid one.
chosenDefinitions[existingIndex] = endpoint;
chosenDescriptors[existingIndex] = descriptor;
}
else
{
keyToIndex[key] = chosenDescriptors.Count;
chosenDefinitions.Add(endpoint);
chosenDescriptors.Add(descriptor);
}

Expand All @@ -221,10 +222,13 @@ private void UpdateEndpointsAndOpenApiDefinitions(
else if (!keyToIndex.ContainsKey(key))
{
keyToIndex[key] = chosenDescriptors.Count;
chosenDefinitions.Add(endpoint);
chosenDescriptors.Add(descriptor);
}
}

_transformer.AddDefinitions(chosenDefinitions.ToArray(), models, modelsByName, schema);

var httpEndpoints = new List<Endpoint>();

foreach (var descriptor in chosenDescriptors)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"paths": {
"/users": {
"get": {
"operationId": "getUsersWithName",
"operationId": "getUsers",
"responses": {
"200": {
"description": null,
Expand All @@ -22,23 +22,20 @@
"type": "array",
"items": {
"required": [
"id",
"name"
"address"
],
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"address": {
"required": [
"street"
],
"type": "object",
"properties": {
"street": {
"type": "string"
},
{
"type": "integer"
}
]
},
"name": {
"type": "string"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"paths": {
"/users": {
"get": {
"operationId": "getUsersWithName",
"operationId": "getUsers",
"responses": {
"200": {
"description": null,
Expand All @@ -17,23 +17,20 @@
"type": "array",
"items": {
"required": [
"id",
"name"
"address"
],
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"address": {
"required": [
"street"
],
"type": "object",
"properties": {
"street": {
"type": "string"
},
{
"type": "integer"
}
]
},
"name": {
"type": "string"
}
}
}
}
Expand Down
Loading