Skip to content

Commit

Permalink
Adding support for QueryResult in Swagger
Browse files Browse the repository at this point in the history
  • Loading branch information
einari committed Jul 18, 2024
1 parent 9ed1619 commit 9f44583
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
27 changes: 27 additions & 0 deletions Source/DotNET/Applications/Queries/QueryMethodExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Cratis. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Reflection;
using Cratis.Reflection;
using Microsoft.AspNetCore.Mvc;

namespace Cratis.Applications.Queries;

/// <summary>
/// Extension methods for methods representing commands.
/// </summary>
public static class QueryMethodExtensions
{
/// <summary>
/// Check if a method is a command.
/// </summary>
/// <param name="methodInfo">The <see cref="MethodInfo"/> to check.</param>
/// <returns>True if it is a command, false if not.</returns>
public static bool IsQuery(this MethodInfo methodInfo) =>
methodInfo.HasAttribute<HttpGetAttribute>() &&
methodInfo.ReturnType != typeof(void) &&
methodInfo.ReturnType != typeof(Task) &&
methodInfo.ReturnType != typeof(ValueTask) &&
!methodInfo.HasAttribute<AspNetResultAttribute>() &&
(!methodInfo.DeclaringType?.HasAttribute<AspNetResultAttribute>() ?? false);
}
1 change: 1 addition & 0 deletions Source/DotNET/Swagger/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ public static void AddConcepts(this SwaggerGenOptions options)
{
options.SchemaFilter<ConceptSchemaFilter>();
options.OperationFilter<CommandResultOperationFilter>();
options.OperationFilter<QueryResultOperationFilter>();
}
}
43 changes: 43 additions & 0 deletions Source/DotNET/Swagger/QueryResultOperationFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Cratis. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Cratis.Applications.Queries;
using Cratis.Concepts;
using Cratis.Reflection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace Cratis.Applications.Swagger;

/// <summary>
/// Represents an implementation of <see cref="IOperationFilter"/> that adds the command result to the operation for command methods.
/// </summary>
/// <param name="schemaGenerator">The <see cref="ISchemaGenerator"/> to use.</param>
public class QueryResultOperationFilter(ISchemaGenerator schemaGenerator) : IOperationFilter
{
/// <inheritdoc/>
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (!context.MethodInfo.IsQuery()) return;

var returnType = context.MethodInfo.GetActualReturnType();

if (returnType.IsConcept())
{
returnType = returnType.GetConceptValueType();
}

var queryResultType = typeof(QueryResult<>).MakeGenericType(returnType);

var schema = schemaGenerator.GenerateSchema(queryResultType, context.SchemaRepository);
var response = operation.Responses.First().Value;
if (response.Content.ContainsKey("application/json"))
{
operation.Responses.First().Value.Content["application/json"].Schema = schema;
}
else
{
response.Content.Add(new("application/json", new() { Schema = schema }));
}
}
}

0 comments on commit 9f44583

Please sign in to comment.