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

Merge master into openapi #1647

Merged
merged 6 commits into from
Nov 27, 2024
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 @@ -217,7 +217,7 @@ public RelationshipAttribute GetRelationshipByPropertyName(string propertyName)
}

/// <summary>
/// Returns all directly and indirectly non-abstract resource types that derive from this resource type.
/// Returns all non-abstract resource types that directly or indirectly derive from this resource type.
/// </summary>
public IReadOnlySet<ResourceType> GetAllConcreteDerivedTypes()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private static List<ActionDescriptor> Expand(ActionDescriptor genericEndpoint, N

ActionDescriptor expandedEndpoint = Clone(genericEndpoint);

RemovePathParameter(expandedEndpoint.Parameters, JsonApiPathParameter.RelationshipName);
RemovePathParameter(expandedEndpoint.Parameters, "relationshipName");

ExpandTemplate(expandedEndpoint.AttributeRouteInfo!, relationshipName);

Expand Down Expand Up @@ -212,12 +212,12 @@ private static FilterDescriptor Clone(FilterDescriptor descriptor)

private static void RemovePathParameter(ICollection<ParameterDescriptor> parameters, string parameterName)
{
ParameterDescriptor relationshipName = parameters.Single(parameterDescriptor => parameterDescriptor.Name == parameterName);
parameters.Remove(relationshipName);
ParameterDescriptor descriptor = parameters.Single(parameterDescriptor => parameterDescriptor.Name == parameterName);
parameters.Remove(descriptor);
}

private static void ExpandTemplate(AttributeRouteInfo route, string expansionParameter)
{
route.Template = route.Template!.Replace(JsonApiRoutingTemplate.RelationshipNameRoutePlaceholder, expansionParameter);
route.Template = route.Template!.Replace("{relationshipName}", expansionParameter);
}
}
16 changes: 0 additions & 16 deletions src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiEndpoint.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,72 +1,38 @@
using System.Reflection;
using JsonApiDotNetCore.Controllers;
using Microsoft.AspNetCore.Mvc;
using JsonApiDotNetCore.Middleware;
using Microsoft.AspNetCore.Mvc.Routing;

namespace JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiMetadata;

internal sealed class EndpointResolver
{
public JsonApiEndpoint? Get(MethodInfo controllerAction)
public static EndpointResolver Instance { get; } = new();

private EndpointResolver()
{
}

public JsonApiEndpoints GetEndpoint(MethodInfo controllerAction)
{
ArgumentGuard.NotNull(controllerAction);

if (!IsJsonApiController(controllerAction))
{
return null;
}

if (IsAtomicOperationsController(controllerAction))
{
return JsonApiEndpoint.PostOperations;
return JsonApiEndpoints.None;
}

HttpMethodAttribute? method = Attribute.GetCustomAttributes(controllerAction, true).OfType<HttpMethodAttribute>().FirstOrDefault();

return ResolveJsonApiEndpoint(method);
IEnumerable<HttpMethodAttribute> httpMethodAttributes = controllerAction.GetCustomAttributes<HttpMethodAttribute>(true);
return httpMethodAttributes.GetJsonApiEndpoint();
}

private static bool IsJsonApiController(MethodInfo controllerAction)
private bool IsJsonApiController(MethodInfo controllerAction)
{
return typeof(CoreJsonApiController).IsAssignableFrom(controllerAction.ReflectedType);
}

private static bool IsAtomicOperationsController(MethodInfo controllerAction)
public bool IsAtomicOperationsController(MethodInfo controllerAction)
{
return typeof(BaseJsonApiOperationsController).IsAssignableFrom(controllerAction.ReflectedType);
}

private static JsonApiEndpoint? ResolveJsonApiEndpoint(HttpMethodAttribute? httpMethod)
{
return httpMethod switch
{
HttpGetAttribute attr => attr.Template switch
{
null => JsonApiEndpoint.GetCollection,
JsonApiRoutingTemplate.PrimaryEndpoint => JsonApiEndpoint.GetSingle,
JsonApiRoutingTemplate.SecondaryEndpoint => JsonApiEndpoint.GetSecondary,
JsonApiRoutingTemplate.RelationshipEndpoint => JsonApiEndpoint.GetRelationship,
_ => null
},
HttpPostAttribute attr => attr.Template switch
{
null => JsonApiEndpoint.PostResource,
JsonApiRoutingTemplate.RelationshipEndpoint => JsonApiEndpoint.PostRelationship,
_ => null
},
HttpPatchAttribute attr => attr.Template switch
{
JsonApiRoutingTemplate.PrimaryEndpoint => JsonApiEndpoint.PatchResource,
JsonApiRoutingTemplate.RelationshipEndpoint => JsonApiEndpoint.PatchRelationship,
_ => null
},
HttpDeleteAttribute attr => attr.Template switch
{
JsonApiRoutingTemplate.PrimaryEndpoint => JsonApiEndpoint.DeleteResource,
JsonApiRoutingTemplate.RelationshipEndpoint => JsonApiEndpoint.DeleteRelationship,
_ => null
},
_ => null
};
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reflection;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Middleware;
using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.Documents;
using JsonApiDotNetCore.Resources.Annotations;
Expand All @@ -12,18 +13,14 @@ namespace JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiMetadata;
/// </summary>
internal sealed class JsonApiEndpointMetadataProvider
{
private readonly EndpointResolver _endpointResolver;
private readonly IControllerResourceMapping _controllerResourceMapping;
private readonly NonPrimaryDocumentTypeFactory _nonPrimaryDocumentTypeFactory;

public JsonApiEndpointMetadataProvider(EndpointResolver endpointResolver, IControllerResourceMapping controllerResourceMapping,
NonPrimaryDocumentTypeFactory nonPrimaryDocumentTypeFactory)
public JsonApiEndpointMetadataProvider(IControllerResourceMapping controllerResourceMapping, NonPrimaryDocumentTypeFactory nonPrimaryDocumentTypeFactory)
{
ArgumentGuard.NotNull(endpointResolver);
ArgumentGuard.NotNull(controllerResourceMapping);
ArgumentGuard.NotNull(nonPrimaryDocumentTypeFactory);

_endpointResolver = endpointResolver;
_controllerResourceMapping = controllerResourceMapping;
_nonPrimaryDocumentTypeFactory = nonPrimaryDocumentTypeFactory;
}
Expand All @@ -32,16 +29,16 @@ public JsonApiEndpointMetadataContainer Get(MethodInfo controllerAction)
{
ArgumentGuard.NotNull(controllerAction);

JsonApiEndpoint? endpoint = _endpointResolver.Get(controllerAction);

if (endpoint == null)
if (EndpointResolver.Instance.IsAtomicOperationsController(controllerAction))
{
throw new NotSupportedException($"Unable to provide metadata for non-JSON:API endpoint '{controllerAction.ReflectedType!.FullName}'.");
return new JsonApiEndpointMetadataContainer(AtomicOperationsRequestMetadata.Instance, AtomicOperationsResponseMetadata.Instance);
}

if (endpoint == JsonApiEndpoint.PostOperations)
JsonApiEndpoints endpoint = EndpointResolver.Instance.GetEndpoint(controllerAction);

if (endpoint == JsonApiEndpoints.None)
{
return new JsonApiEndpointMetadataContainer(AtomicOperationsRequestMetadata.Instance, AtomicOperationsResponseMetadata.Instance);
throw new NotSupportedException($"Unable to provide metadata for non-JSON:API endpoint '{controllerAction.ReflectedType!.FullName}'.");
}

ResourceType? primaryResourceType = _controllerResourceMapping.GetResourceTypeForController(controllerAction.ReflectedType);
Expand All @@ -51,19 +48,19 @@ public JsonApiEndpointMetadataContainer Get(MethodInfo controllerAction)
throw new UnreachableCodeException();
}

IJsonApiRequestMetadata? requestMetadata = GetRequestMetadata(endpoint.Value, primaryResourceType);
IJsonApiResponseMetadata? responseMetadata = GetResponseMetadata(endpoint.Value, primaryResourceType);
IJsonApiRequestMetadata? requestMetadata = GetRequestMetadata(endpoint, primaryResourceType);
IJsonApiResponseMetadata? responseMetadata = GetResponseMetadata(endpoint, primaryResourceType);
return new JsonApiEndpointMetadataContainer(requestMetadata, responseMetadata);
}

private IJsonApiRequestMetadata? GetRequestMetadata(JsonApiEndpoint endpoint, ResourceType primaryResourceType)
private IJsonApiRequestMetadata? GetRequestMetadata(JsonApiEndpoints endpoint, ResourceType primaryResourceType)
{
return endpoint switch
{
JsonApiEndpoint.PostResource => GetPostResourceRequestMetadata(primaryResourceType.ClrType),
JsonApiEndpoint.PatchResource => GetPatchResourceRequestMetadata(primaryResourceType.ClrType),
JsonApiEndpoint.PostRelationship or JsonApiEndpoint.PatchRelationship or JsonApiEndpoint.DeleteRelationship => GetRelationshipRequestMetadata(
primaryResourceType.Relationships, endpoint != JsonApiEndpoint.PatchRelationship),
JsonApiEndpoints.Post => GetPostResourceRequestMetadata(primaryResourceType.ClrType),
JsonApiEndpoints.Patch => GetPatchResourceRequestMetadata(primaryResourceType.ClrType),
JsonApiEndpoints.PostRelationship or JsonApiEndpoints.PatchRelationship or JsonApiEndpoints.DeleteRelationship => GetRelationshipRequestMetadata(
primaryResourceType.Relationships, endpoint != JsonApiEndpoints.PatchRelationship),
_ => null
};
}
Expand Down Expand Up @@ -92,14 +89,14 @@ private RelationshipRequestMetadata GetRelationshipRequestMetadata(IEnumerable<R
return new RelationshipRequestMetadata(requestDocumentTypesByRelationshipName);
}

private IJsonApiResponseMetadata? GetResponseMetadata(JsonApiEndpoint endpoint, ResourceType primaryResourceType)
private IJsonApiResponseMetadata? GetResponseMetadata(JsonApiEndpoints endpoint, ResourceType primaryResourceType)
{
return endpoint switch
{
JsonApiEndpoint.GetCollection or JsonApiEndpoint.GetSingle or JsonApiEndpoint.PostResource or JsonApiEndpoint.PatchResource =>
GetPrimaryResponseMetadata(primaryResourceType.ClrType, endpoint == JsonApiEndpoint.GetCollection),
JsonApiEndpoint.GetSecondary => GetSecondaryResponseMetadata(primaryResourceType.Relationships),
JsonApiEndpoint.GetRelationship => GetRelationshipResponseMetadata(primaryResourceType.Relationships),
JsonApiEndpoints.GetCollection or JsonApiEndpoints.GetSingle or JsonApiEndpoints.Post or JsonApiEndpoints.Patch => GetPrimaryResponseMetadata(
primaryResourceType.ClrType, endpoint == JsonApiEndpoints.GetCollection),
JsonApiEndpoints.GetSecondary => GetSecondaryResponseMetadata(primaryResourceType.Relationships),
JsonApiEndpoints.GetRelationship => GetRelationshipResponseMetadata(primaryResourceType.Relationships),
_ => null
};
}
Expand Down

This file was deleted.

This file was deleted.

Loading
Loading