Skip to content

Commit

Permalink
Remove JsonApiEndpoint, reuse logic from base library
Browse files Browse the repository at this point in the history
  • Loading branch information
bkoelman committed Nov 27, 2024
1 parent 900f20c commit 11aafa4
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 175 deletions.
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

0 comments on commit 11aafa4

Please sign in to comment.