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
TResourceThe resource type.
TIdThe resource identifier type.
- Inheritance
-
JsonApiResourceDefinition<TResource, TId>
- Implements
-
IResourceDefinition<TResource, TId>
- Inherited Members
Constructors
JsonApiResourceDefinition(IResourceGraph)
public JsonApiResourceDefinition(IResourceGraph resourceGraph)
Parameters
resourceGraphIResourceGraph
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
keySelectorsJsonApiResourceDefinition<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
resourceTResource
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
leftResourceTResourceIdentifier of the left resource. The indication "left" specifies that
hasManyRelationshipis declared onTResource. In contrast to other relationship methods, this value is not retrieved from the underlying data store, except in the following two cases:hasManyRelationshipis 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.
hasManyRelationshipHasManyAttributeThe to-many relationship being added to.
rightResourceIdsISet<IIdentifiable>The set of resource identifiers to add to the to-many relationship, coming from the request.
cancellationTokenCancellationTokenPropagates 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
existingFilterFilterExpressionAn optional existing filter, coming from query string. Can be
null.
Returns
- FilterExpression
The new filter, or
nullto 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
existingIncludesIImmutableSet<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
existingPaginationPaginationExpressionAn optional existing pagination, coming from query string. Can be
null.
Returns
- PaginationExpression
The changed pagination, or
nullto 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
existingSortSortExpressionAn optional existing sort order, coming from query string. Can be
null.
Returns
- SortExpression
The new sort order, or
nullto 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
existingSparseFieldSetSparseFieldSetExpressionThe incoming sparse fieldset from query string. At query execution time, this is
nullif 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
nullto 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
resourceTResourceThe 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
resourceTResourceThe original resource retrieved from the underlying data store, or a freshly instantiated resource in case of a POST resource request.
writeOperationWriteOperationKindIdentifies 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.
cancellationTokenCancellationTokenPropagates 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
leftResourceTResourceIdentifier of the left resource. The indication "left" specifies that
hasManyRelationshipis 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.hasManyRelationshipHasManyAttributeThe to-many relationship being removed from.
rightResourceIdsISet<IIdentifiable>The set of resource identifiers to remove from the to-many relationship, coming from the request.
cancellationTokenCancellationTokenPropagates 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
resourceTResourceThe 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
leftResourceTResourceThe original resource as retrieved from the underlying data store. The indication "left" specifies that
hasManyRelationshipis declared onTResource.hasManyRelationshipHasManyAttributeThe to-many relationship being set.
rightResourceIdsISet<IIdentifiable>The set of resource identifiers to replace any existing set with, coming from the request.
writeOperationWriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource and SetRelationship.
cancellationTokenCancellationTokenPropagates 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
leftResourceTResourceThe original resource as retrieved from the underlying data store. The indication "left" specifies that
hasOneRelationshipis declared onTResource.hasOneRelationshipHasOneAttributeThe to-one relationship being set.
rightResourceIdIIdentifiableThe new resource identifier (or
nullto clear the relationship), coming from the request.writeOperationWriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource and SetRelationship.
cancellationTokenCancellationTokenPropagates notification that request handling should be canceled.
Returns
- Task<IIdentifiable>
The replacement resource identifier, or
nullto clear the relationship. ReturnsrightResourceIdby 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
resourceTResourceThe resource as written to the underlying data store.
writeOperationWriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource, DeleteResource, SetRelationship , AddToRelationship and RemoveFromRelationship.
cancellationTokenCancellationTokenPropagates 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
resourceTResourceThe 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
writeOperationis DeleteResource, AddToRelationship or RemoveFromRelationship, this is an empty object with only the Id property set, because for those endpoints no resource is retrieved upfront.writeOperationWriteOperationKindIdentifies the logical write operation for which this method was called. Possible values: CreateResource, UpdateResource, DeleteResource, SetRelationship , AddToRelationship and RemoveFromRelationship.
cancellationTokenCancellationTokenPropagates notification that request handling should be canceled.