Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: path item reference implementation #2096

Merged
merged 3 commits into from
Jan 28, 2025
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
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public override void Visit(OpenApiSchema schema)
base.Visit(schema);
}

public override void Visit(OpenApiPathItem pathItem)
public override void Visit(IOpenApiPathItem pathItem)
{
if (pathItem.Operations.TryGetValue(OperationType.Put, out var value) &&
value.OperationId != null)
Expand Down Expand Up @@ -81,13 +81,13 @@ public override void Visit(OpenApiOperation operation)
operationId = ResolveODataCastOperationId(operationId);
operationId = ResolveByRefOperationId(operationId);
// Verb segment resolution should always be last. user.get -> user_Get
operationId = ResolveVerbSegmentInOpertationId(operationId);
operationId = ResolveVerbSegmentInOperationId(operationId);

operation.OperationId = operationId;
base.Visit(operation);
}

private static string ResolveVerbSegmentInOpertationId(string operationId)
private static string ResolveVerbSegmentInOperationId(string operationId)
{
var charPos = operationId.LastIndexOf('.', operationId.Length - 1);
if (operationId.Contains('_', StringComparison.OrdinalIgnoreCase) || charPos < 0)
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi.Hidi/StatsVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public override void Visit(IDictionary<string, IOpenApiHeader> headers)

public int PathItemCount { get; set; }

public override void Visit(OpenApiPathItem pathItem)
public override void Visit(IOpenApiPathItem pathItem)
{
PathItemCount++;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi.Workbench/StatsVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public override void Visit(IDictionary<string, IOpenApiHeader> headers)

public int PathItemCount { get; set; }

public override void Visit(OpenApiPathItem pathItem)
public override void Visit(IOpenApiPathItem pathItem)
{
PathItemCount++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ public interface IOpenApiCallback : IOpenApiSerializable, IOpenApiReadOnlyExtens
/// <summary>
/// A Path Item Object used to define a callback request and expected responses.
/// </summary>
public Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get; }
public Dictionary<RuntimeExpression, IOpenApiPathItem> PathItems { get; }
}
28 changes: 28 additions & 0 deletions src/Microsoft.OpenApi/Models/Interfaces/IOpenApiPathItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

using System.Collections.Generic;
using Microsoft.OpenApi.Interfaces;

namespace Microsoft.OpenApi.Models.Interfaces;

/// <summary>
/// Defines the base properties for the path item object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiPathItem : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
{
/// <summary>
/// Gets the definition of operations on this path.
/// </summary>
public IDictionary<OperationType, OpenApiOperation> Operations { get; }

/// <summary>
/// An alternative server array to service all operations in this path.
/// </summary>
public IList<OpenApiServer> Servers { get; }

/// <summary>
/// A list of parameters that are applicable for all the operations described under this path.
/// These parameters can be overridden at the operation level, but cannot be removed there.
/// </summary>
public IList<IOpenApiParameter> Parameters { get; }
}
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.OpenApi.Models
public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiCallback
{
/// <inheritdoc/>
public Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get; set; }
public Dictionary<RuntimeExpression, IOpenApiPathItem> PathItems { get; set; }
= [];


Expand All @@ -40,11 +40,11 @@ public OpenApiCallback(IOpenApiCallback callback)
}

/// <summary>
/// Add a <see cref="OpenApiPathItem"/> into the <see cref="PathItems"/>.
/// Add a <see cref="IOpenApiPathItem"/> into the <see cref="PathItems"/>.
/// </summary>
/// <param name="expression">The runtime expression.</param>
/// <param name="pathItem">The path item.</param>
public void AddPathItem(RuntimeExpression expression, OpenApiPathItem pathItem)
public void AddPathItem(RuntimeExpression expression, IOpenApiPathItem pathItem)
{
Utils.CheckArgumentNull(expression);
Utils.CheckArgumentNull(pathItem);
Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiComponents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible
public IDictionary<string, IOpenApiCallback>? Callbacks { get; set; } = new Dictionary<string, IOpenApiCallback>();

/// <summary>
/// An object to hold reusable <see cref="OpenApiPathItem"/> Object.
/// An object to hold reusable <see cref="IOpenApiPathItem"/> Object.
/// </summary>
public IDictionary<string, OpenApiPathItem>? PathItems { get; set; } = new Dictionary<string, OpenApiPathItem>();
public IDictionary<string, IOpenApiPathItem>? PathItems { get; set; } = new Dictionary<string, IOpenApiPathItem>();

/// <summary>
/// This object MAY be extended with Specification Extensions.
Expand All @@ -94,7 +94,7 @@ public OpenApiComponents(OpenApiComponents? components)
SecuritySchemes = components?.SecuritySchemes != null ? new Dictionary<string, OpenApiSecurityScheme>(components.SecuritySchemes) : null;
Links = components?.Links != null ? new Dictionary<string, IOpenApiLink>(components.Links) : null;
Callbacks = components?.Callbacks != null ? new Dictionary<string, IOpenApiCallback>(components.Callbacks) : null;
PathItems = components?.PathItems != null ? new Dictionary<string, OpenApiPathItem>(components.PathItems) : null;
PathItems = components?.PathItems != null ? new Dictionary<string, IOpenApiPathItem>(components.PathItems) : null;
Extensions = components?.Extensions != null ? new Dictionary<string, IOpenApiExtension>(components.Extensions) : null;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class OpenApiDocument : IOpenApiSerializable, IOpenApiExtensible, IOpenAp
/// A map of requests initiated other than by an API call, for example by an out of band registration.
/// The key name is a unique string to refer to each webhook, while the (optionally referenced) Path Item Object describes a request that may be initiated by the API provider and the expected responses
/// </summary>
public IDictionary<string, OpenApiPathItem>? Webhooks { get; set; } = new Dictionary<string, OpenApiPathItem>();
public IDictionary<string, IOpenApiPathItem>? Webhooks { get; set; } = new Dictionary<string, IOpenApiPathItem>();

/// <summary>
/// An element to hold various schemas for the specification.
Expand Down Expand Up @@ -113,7 +113,7 @@ public OpenApiDocument(OpenApiDocument? document)
JsonSchemaDialect = document?.JsonSchemaDialect ?? JsonSchemaDialect;
Servers = document?.Servers != null ? new List<OpenApiServer>(document.Servers) : null;
Paths = document?.Paths != null ? new(document?.Paths) : new OpenApiPaths();
Webhooks = document?.Webhooks != null ? new Dictionary<string, OpenApiPathItem>(document.Webhooks) : null;
Webhooks = document?.Webhooks != null ? new Dictionary<string, IOpenApiPathItem>(document.Webhooks) : null;
Components = document?.Components != null ? new(document?.Components) : null;
SecurityRequirements = document?.SecurityRequirements != null ? new List<OpenApiSecurityRequirement>(document.SecurityRequirements) : null;
Tags = document?.Tags != null ? new List<OpenApiTag>(document.Tags) : null;
Expand Down Expand Up @@ -612,7 +612,7 @@ public bool AddComponent<T>(string id, T componentToRegister)
Components.Callbacks.Add(id, openApiCallback);
break;
case OpenApiPathItem openApiPathItem:
Components.PathItems ??= new Dictionary<string, OpenApiPathItem>();
Components.PathItems ??= new Dictionary<string, IOpenApiPathItem>();
Components.PathItems.Add(id, openApiPathItem);
break;
case OpenApiExample openApiExample:
Expand Down
58 changes: 17 additions & 41 deletions src/Microsoft.OpenApi/Models/OpenApiPathItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,49 +13,26 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Path Item Object: to describe the operations available on a single path.
/// </summary>
public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable
public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable, IOpenApiPathItem
{
/// <summary>
/// An optional, string summary, intended to apply to all operations in this path.
/// </summary>
public virtual string Summary { get; set; }
/// <inheritdoc/>
public string Summary { get; set; }

/// <summary>
/// An optional, string description, intended to apply to all operations in this path.
/// </summary>
public virtual string Description { get; set; }
/// <inheritdoc/>
public string Description { get; set; }

/// <summary>
/// Gets the definition of operations on this path.
/// </summary>
public virtual IDictionary<OperationType, OpenApiOperation> Operations { get; set; }
/// <inheritdoc/>
public IDictionary<OperationType, OpenApiOperation> Operations { get; set; }
= new Dictionary<OperationType, OpenApiOperation>();

/// <summary>
/// An alternative server array to service all operations in this path.
/// </summary>
public virtual IList<OpenApiServer> Servers { get; set; } = new List<OpenApiServer>();

/// <summary>
/// A list of parameters that are applicable for all the operations described under this path.
/// These parameters can be overridden at the operation level, but cannot be removed there.
/// </summary>
public virtual IList<IOpenApiParameter> Parameters { get; set; } = new List<IOpenApiParameter>();
/// <inheritdoc/>
public IList<OpenApiServer> Servers { get; set; } = [];

/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public virtual IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
/// <inheritdoc/>
public IList<IOpenApiParameter> Parameters { get; set; } = [];

/// <summary>
/// Indicates if object is populated with data or is just a reference to the data
/// </summary>
public bool UnresolvedReference { get; set; }

/// <summary>
/// Reference object.
/// </summary>
public OpenApiReference Reference { get; set; }
/// <inheritdoc/>
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();

/// <summary>
/// Add one operation into this path item.
Expand All @@ -75,30 +52,29 @@ public OpenApiPathItem() { }
/// <summary>
/// Initializes a clone of an <see cref="OpenApiPathItem"/> object
/// </summary>
public OpenApiPathItem(OpenApiPathItem pathItem)
public OpenApiPathItem(IOpenApiPathItem pathItem)
{
Utils.CheckArgumentNull(pathItem);
Summary = pathItem?.Summary ?? Summary;
Description = pathItem?.Description ?? Description;
Operations = pathItem?.Operations != null ? new Dictionary<OperationType, OpenApiOperation>(pathItem.Operations) : null;
Servers = pathItem?.Servers != null ? new List<OpenApiServer>(pathItem.Servers) : null;
Parameters = pathItem?.Parameters != null ? new List<IOpenApiParameter>(pathItem.Parameters) : null;
Extensions = pathItem?.Extensions != null ? new Dictionary<string, IOpenApiExtension>(pathItem.Extensions) : null;
UnresolvedReference = pathItem?.UnresolvedReference ?? UnresolvedReference;
Reference = pathItem?.Reference != null ? new(pathItem?.Reference) : null;
}

/// <summary>
/// Serialize <see cref="OpenApiPathItem"/> to Open Api v3.1
/// </summary>
public virtual void SerializeAsV31(IOpenApiWriter writer)
public void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
}

/// <summary>
/// Serialize <see cref="OpenApiPathItem"/> to Open Api v3.0
/// </summary>
public virtual void SerializeAsV3(IOpenApiWriter writer)
public void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
}
Expand Down
4 changes: 3 additions & 1 deletion src/Microsoft.OpenApi/Models/OpenApiPaths.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.Models.Interfaces;

namespace Microsoft.OpenApi.Models
{
/// <summary>
/// Paths object.
/// </summary>
public class OpenApiPaths : OpenApiExtensibleDictionary<OpenApiPathItem>
public class OpenApiPaths : OpenApiExtensibleDictionary<IOpenApiPathItem>
{
/// <summary>
/// Parameterless constructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal OpenApiCallbackReference(OpenApiCallback target, string referenceId):ba
}

/// <inheritdoc/>
public Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get => Target?.PathItems; }
public Dictionary<RuntimeExpression, IOpenApiPathItem> PathItems { get => Target?.PathItems; }

/// <inheritdoc/>
public IDictionary<string, IOpenApiExtension> Extensions { get => Target?.Extensions; }
Expand Down
Loading
Loading