Skip to content

Extend ResourceDefinition #477

Closed
Closed
@wisepotato

Description

@wisepotato

Description

To allow for greater flexibility and reliability using filters we need to change a few things:

We need to change the dependency on Include(string path) in

https://github.com/aspnet/EntityFrameworkCore/blob/473dafce1d2b2e2e2dfd49eb085b9c4bc220658a/src/EFCore/EntityFrameworkQueryableExtensions.cs#L2452-L2469

We then need to make sure that when we have the following cases:

users?include=posts
posts?include=users

and we have a ResourceDefinition on users, that on both urls the Users get filtered. An example of this would be a rule that the current user that is requesting the url cannot see user with an id of 4. Or that a user cannot patch a post with a certain type.

This will require a change in ResourceDefinition and the implementation thereof in the Service and Repository layer.

The repository will need to be changed:

public virtual IQueryable<TEntity> Include(IQueryable<TEntity> entities, string relationshipName)
{
if (string.IsNullOrWhiteSpace(relationshipName)) throw new JsonApiException(400, "Include parameter must not be empty if provided");
var relationshipChain = relationshipName.Split('.');
// variables mutated in recursive loop
// TODO: make recursive method
string internalRelationshipPath = null;
var entity = _jsonApiContext.RequestEntity;
for (var i = 0; i < relationshipChain.Length; i++)
{
var requestedRelationship = relationshipChain[i];
var relationship = entity.Relationships.FirstOrDefault(r => r.PublicRelationshipName == requestedRelationship);
if (relationship == null)
{
throw new JsonApiException(400, $"Invalid relationship {requestedRelationship} on {entity.EntityName}",
$"{entity.EntityName} does not have a relationship named {requestedRelationship}");
}
if (relationship.CanInclude == false)
{
throw new JsonApiException(400, $"Including the relationship {requestedRelationship} on {entity.EntityName} is not allowed");
}
internalRelationshipPath = (internalRelationshipPath == null)
? relationship.RelationshipPath
: $"{internalRelationshipPath}.{relationship.RelationshipPath}";
if(i < relationshipChain.Length)
entity = _jsonApiContext.ResourceGraph.GetContextEntity(relationship.Type);
}
return entities.Include(internalRelationshipPath);
}

Environment

  • JsonApiDotNetCore Version: v3.0.0

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions