Class JsonApiResourceDefinition<TResource, TId>
- Namespace
- JsonApiDotNetCore.Resources
- Assembly
- JsonApiDotNetCore.dll
Provides an extensibility point to add business logic that is resource-oriented instead of endpoint-oriented.
[PublicAPI]
public class JsonApiResourceDefinition<TResource, TId> : IResourceDefinition<TResource, TId> where TResource : class, IIdentifiable<TId>
Type Parameters
TResource
The resource type.
TId
The resource identifier type.
- Inheritance
-
JsonApiResourceDefinition<TResource, TId>
- Implements
-
IResourceDefinition<TResource, TId>
- Inherited Members
Constructors
JsonApiResourceDefinition(IResourceGraph)
public JsonApiResourceDefinition(IResourceGraph resourceGraph)
Parameters
resourceGraph
IResourceGraph
Properties
ResourceGraph
protected IResourceGraph ResourceGraph { get; }
Property Value
ResourceType
Provides metadata for the resource type TResource
.
protected ResourceType ResourceType { get; }
Property Value
Methods
CreateSortExpressionFromLambda(PropertySortOrder)
Creates a SortExpression from a lambda expression.
protected virtual SortExpression CreateSortExpressionFromLambda(JsonApiResourceDefinition<TResource, TId>.PropertySortOrder keySelectors)
Parameters
keySelectors
JsonApiResourceDefinition<TResource, TId>.PropertySortOrder
Returns
Examples
var sort = CreateSortExpressionFromLambda(new PropertySortOrder
{
(blog => blog.Author.Name.LastName, ListSortDirection.Ascending),
(blog => blog.Posts.Count, ListSortDirection.Descending),
(blog => blog.Title, ListSortDirection.Ascending)
});
GetMeta(TResource)
Enables to add JSON:API meta information, specific to this resource.
public virtual IDictionary<string, object?>? GetMeta(TResource resource)
Parameters
resource
TResource
Returns
OnAddToRelationshipAsync(TResource, HasManyAttribute, ISet<IIdentifiable>, CancellationToken)
Executes before adding resources to the right side of a to-many relationship, as part of a POST relationship request.
Implementing this method enables to perform validations and make changes to rightResourceIds
, before the relationship is updated.
public virtual Task OnAddToRelationshipAsync(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
Parameters
leftResource
TResourceIdentifier of the left resource. The indication "left" specifies that
hasManyRelationship
is declared onTResource
. In contrast to other relationship methods, this value is not retrieved from the underlying data store, except in the following two cases:hasManyRelationship
is a many-to-many relationship. This is required to prevent failure when already assigned.- The left resource type is part of a type hierarchy. This ensures your business logic runs against the actually stored type.
hasManyRelationship
HasManyAttributeThe to-many relationship being added to.
rightResourceIds
ISet<IIdentifiable>The set of resource identifiers to add to the to-many relationship, coming from the request.
cancellationToken
CancellationTokenPropagates notification that request handling should be canceled.
Returns
OnApplyFilter(FilterExpression?)
Enables to extend, replace or remove a filter that is being applied on a set of this resource type.
public virtual FilterExpression? OnApplyFilter(FilterExpression? existingFilter)
Parameters
existingFilter
FilterExpressionAn optional existing filter, coming from query string. Can be
null
.
Returns
- FilterExpression
The new filter, or
null
to disable the existing filter.
OnApplyIncludes(IImmutableSet<IncludeElementExpression>)
Enables to extend, replace or remove includes that are being applied on this resource type.
public virtual IImmutableSet<IncludeElementExpression> OnApplyIncludes(IImmutableSet<IncludeElementExpression> existingIncludes)
Parameters
existingIncludes
IImmutableSet<IncludeElementExpression>An optional existing set of includes, coming from query string. Never
null
, but may be empty.
Returns
- IImmutableSet<IncludeElementExpression>
The new set of includes. Return an empty collection to remove all inclusions (never return
null
).
OnApplyPagination(PaginationExpression?)
Enables to extend, replace or remove pagination that is being applied on a set of this resource type.
public virtual PaginationExpression? OnApplyPagination(PaginationExpression? existingPagination)
Parameters
existingPagination
PaginationExpressionAn optional existing pagination, coming from query string. Can be
null
.
Returns
- PaginationExpression
The changed pagination, or
null
to use the first page with default size from options. To disable pagination, set PageSize tonull
.
OnApplySort(SortExpression?)
Enables to extend, replace or remove a sort order that is being applied on a set of this resource type. Tip: Use CreateSortExpressionFromLambda(PropertySortOrder) to build from a lambda expression.
public virtual SortExpression? OnApplySort(SortExpression? existingSort)
Parameters
existingSort
SortExpressionAn optional existing sort order, coming from query string. Can be
null
.
Returns
- SortExpression
The new sort order, or
null
to disable the existing sort order and sort by ID.
OnApplySparseFieldSet(SparseFieldSetExpression?)
Enables to extend, replace or remove a sparse fieldset that is being applied on a set of this resource type. Tip: Use Including<TResource>(SparseFieldSetExpression?, Expression<Func<TResource, object?>>, IResourceGraph) and Excluding<TResource>(SparseFieldSetExpression?, Expression<Func<TResource, object?>>, IResourceGraph) to safely change the fieldset without worrying about nulls.
public virtual SparseFieldSetExpression? OnApplySparseFieldSet(SparseFieldSetExpression? existingSparseFieldSet)
Parameters
existingSparseFieldSet
SparseFieldSetExpressionThe incoming sparse fieldset from query string. At query execution time, this is
null
if the query string contains no sparse fieldset. At serialization time, this contains all viewable fields if the query string contains no sparse fieldset.
Returns
- SparseFieldSetExpression
The new sparse fieldset, or
null
to discard the existing sparse fieldset and select all viewable fields.
Remarks
This method executes twice for a single request: first to select which fields to retrieve from the data store and then to select which fields to serialize. Including extra fields from this method will retrieve them, but not include them in the json output. This enables you to expose calculated properties whose value depends on a field that is not in the sparse fieldset.
OnDeserialize(TResource)
Executes after a resource has been deserialized from an incoming request body.
public virtual void OnDeserialize(TResource resource)
Parameters
resource
TResourceThe deserialized resource.
OnPrepareWriteAsync(TResource, WriteOperationKind, CancellationToken)
Executes after the original version of the resource has been retrieved from the underlying data store, as part of a write request.
Implementing this method enables to perform validations and make changes to resource
, before the fields from the request are
copied into it.
For POST resource requests, this method is typically used to assign property default values or to set required relationships by side-loading the related resources and linking them.
public virtual Task OnPrepareWriteAsync(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
Parameters
resource
TResourceThe original resource retrieved from the underlying data store, or a freshly instantiated resource in case of a POST resource request.
writeOperation
WriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource, SetRelationship and RemoveFromRelationship. Note this intentionally excludes DeleteResource and AddToRelationship, because for those endpoints no resource is retrieved upfront.
cancellationToken
CancellationTokenPropagates notification that request handling should be canceled.
Returns
OnRegisterQueryableHandlersForQueryStringParameters()
Enables to adapt the Entity Framework Core IQueryable<T> query, based on custom query string parameters. Note this only works on primary resource requests, such as /articles, but not on /blogs/1/articles or /blogs?include=articles.
public virtual QueryStringParameterHandlers<TResource>? OnRegisterQueryableHandlersForQueryStringParameters()
Returns
- QueryStringParameterHandlers<TResource>
Examples
protected override QueryStringParameterHandlers OnRegisterQueryableHandlersForQueryStringParameters()
{
return new QueryStringParameterHandlers
{
["isActive"] = (source, parameterValue) => source
.Include(model => model.Children)
.Where(model => model.LastUpdateTime > DateTime.Now.AddMonths(-1)),
["isHighRisk"] = FilterByHighRisk
};
}
private static IQueryable<Model> FilterByHighRisk(IQueryable<Model> source, StringValues parameterValue)
{
bool isFilterOnHighRisk = bool.Parse(parameterValue);
return isFilterOnHighRisk ? source.Where(model => model.RiskLevel >= 5) : source.Where(model => model.RiskLevel < 5);
}
OnRemoveFromRelationshipAsync(TResource, HasManyAttribute, ISet<IIdentifiable>, CancellationToken)
Executes before removing resources from the right side of a to-many relationship, as part of a DELETE relationship request.
Implementing this method enables to perform validations and make changes to rightResourceIds
, before the relationship is updated.
public virtual Task OnRemoveFromRelationshipAsync(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds, CancellationToken cancellationToken)
Parameters
leftResource
TResourceIdentifier of the left resource. The indication "left" specifies that
hasManyRelationship
is declared onTResource
. In contrast to other relationship methods, only the left ID and only the subset of right resources to be removed are retrieved from the underlying data store.hasManyRelationship
HasManyAttributeThe to-many relationship being removed from.
rightResourceIds
ISet<IIdentifiable>The set of resource identifiers to remove from the to-many relationship, coming from the request.
cancellationToken
CancellationTokenPropagates notification that request handling should be canceled.
Returns
OnSerialize(TResource)
Executes before a (primary or included) resource is serialized into an outgoing response body.
public virtual void OnSerialize(TResource resource)
Parameters
resource
TResourceThe serialized resource.
OnSetToManyRelationshipAsync(TResource, HasManyAttribute, ISet<IIdentifiable>, WriteOperationKind, CancellationToken)
Executes before setting the resources at the right side of a to-many relationship. This replaces on existing set.
Implementing this method enables to perform validations and make changes to rightResourceIds
, before the relationship is updated.
public virtual Task OnSetToManyRelationshipAsync(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds, WriteOperationKind writeOperation, CancellationToken cancellationToken)
Parameters
leftResource
TResourceThe original resource as retrieved from the underlying data store. The indication "left" specifies that
hasManyRelationship
is declared onTResource
.hasManyRelationship
HasManyAttributeThe to-many relationship being set.
rightResourceIds
ISet<IIdentifiable>The set of resource identifiers to replace any existing set with, coming from the request.
writeOperation
WriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource and SetRelationship.
cancellationToken
CancellationTokenPropagates notification that request handling should be canceled.
Returns
OnSetToOneRelationshipAsync(TResource, HasOneAttribute, IIdentifiable?, WriteOperationKind, CancellationToken)
Executes before setting (or clearing) the resource at the right side of a to-one relationship.
Implementing this method enables to perform validations and change rightResourceId
, before the relationship is updated.
public virtual Task<IIdentifiable?> OnSetToOneRelationshipAsync(TResource leftResource, HasOneAttribute hasOneRelationship, IIdentifiable? rightResourceId, WriteOperationKind writeOperation, CancellationToken cancellationToken)
Parameters
leftResource
TResourceThe original resource as retrieved from the underlying data store. The indication "left" specifies that
hasOneRelationship
is declared onTResource
.hasOneRelationship
HasOneAttributeThe to-one relationship being set.
rightResourceId
IIdentifiableThe new resource identifier (or
null
to clear the relationship), coming from the request.writeOperation
WriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource and SetRelationship.
cancellationToken
CancellationTokenPropagates notification that request handling should be canceled.
Returns
- Task<IIdentifiable>
The replacement resource identifier, or
null
to clear the relationship. ReturnsrightResourceId
by default.
OnWriteSucceededAsync(TResource, WriteOperationKind, CancellationToken)
Executes after successfully writing the changed resource to the underlying data store, as part of a write request.
Implementing this method enables to run additional logic, for example enqueue a notification message on a service bus.
public virtual Task OnWriteSucceededAsync(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
Parameters
resource
TResourceThe resource as written to the underlying data store.
writeOperation
WriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource, DeleteResource, SetRelationship , AddToRelationship and RemoveFromRelationship.
cancellationToken
CancellationTokenPropagates notification that request handling should be canceled.
Returns
OnWritingAsync(TResource, WriteOperationKind, CancellationToken)
Executes before writing the changed resource to the underlying data store, as part of a write request.
Implementing this method enables to perform validations and make changes to resource
, after the fields from the request have been
copied into it.
An example usage is to set the last-modification timestamp, overwriting the value from the incoming request.
Another use case is to add a notification message to an outbox table, which gets committed along with the resource write in a single transaction (see https://microservices.io/patterns/data/transactional-outbox.html).
public virtual Task OnWritingAsync(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
Parameters
resource
TResourceThe original resource retrieved from the underlying data store (or a freshly instantiated resource in case of a POST resource request), updated with the changes from the incoming request. Exception: In case
writeOperation
is DeleteResource, AddToRelationship or RemoveFromRelationship, this is an empty object with only the Id property set, because for those endpoints no resource is retrieved upfront.writeOperation
WriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource, DeleteResource, SetRelationship , AddToRelationship and RemoveFromRelationship.
cancellationToken
CancellationTokenPropagates notification that request handling should be canceled.