You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Customization can be done at any of these layers. However, it is recommended that you make your customizations at the service or the repository layer when possible, to keep the controllers free of unnecessary logic.
14
-
You can use the following as a general rule of thumb for where to put business logic:
17
+
Resource definition callbacks are invoked from the built-in resource service/repository layers, as well as from the serializer.
18
+
For example, `IResourceDefinition.OnSerialize` is invoked whenever a resource is sent back to the client, irrespective of the endpoint.
19
+
Likewise, `IResourceDefinition.OnSetToOneRelationshipAsync` is called from a patch-resource-with-relationships endpoint, as well as from patch-relationship.
15
20
16
-
-`Controller`: simple validation logic that should result in the return of specific HTTP status codes, such as model validation
17
-
-`IResourceService`: advanced business logic and replacement of data access mechanisms
18
-
-`IResourceRepository`: custom logic that builds on the Entity Framework Core APIs
21
+
Customization can be done at any of these extensibility points. It is usually sufficient to place your business logic in a resource definition, but depending
22
+
on your needs, you may want to replace other parts by deriving from the built-in classes and override virtual methods or call their protected base methods.
19
23
20
-
## Replacing Services
24
+
## Replacing injected services
21
25
22
-
**Note:** If you are using auto-discovery, resource servicesand repositories will be automatically registered for you.
26
+
**Note:** If you are using auto-discovery, then resource services, repositories and resource definitions will be automatically registered for you.
23
27
24
-
Replacing services and repositories is done on a per-resource basis and can be done through dependency injection in your Startup.cs file.
28
+
Replacing built-in services is done on a per-resource basis and can be done through dependency injection in your Startup.cs file.
29
+
For convenience, extension methods are provided to register layers on all their implemented interfaces.
@@ -196,14 +206,14 @@ public class EmployeeDefinition : JsonApiResourceDefinition<Employee>
196
206
}
197
207
```
198
208
199
-
## Custom query string parameters
209
+
###Custom query string parameters
200
210
201
211
_since v3_
202
212
203
213
You can define additional query string parameters with the LINQ expression that should be used.
204
214
If the key is present in a query string, the supplied LINQ expression will be added to the database query.
205
215
206
-
Note this directly influences the Entity Framework Core `IQueryable`. As opposed to using `OnApplyFilter`, this enables the full range of EF Core functionality.
216
+
Note this directly influences the Entity Framework Core `IQueryable`. As opposed to using `OnApplyFilter`, this enables the full range of EF Core operators.
207
217
But it only works on primary resource endpoints (for example: /articles, but not on /blogs/1/articles or /blogs?include=articles).
208
218
209
219
```c#
@@ -237,12 +247,3 @@ public class ItemDefinition : JsonApiResourceDefinition<Item>
237
247
}
238
248
}
239
249
```
240
-
241
-
## Using Resource Definitions prior to v3
242
-
243
-
Prior to the introduction of auto-discovery, you needed to register the
Copy file name to clipboardExpand all lines: docs/usage/reading/filtering.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -119,7 +119,7 @@ GET /articles?filter[caption]=tech&filter=expr:equals(caption,'cooking')) HTTP/1
119
119
120
120
There are multiple ways you can add custom filters:
121
121
122
-
1. Implementing `IResourceDefinition.OnApplyFilter` (see [here](~/usage/extensibility/resource-definitions.md#exclude-soft-deleted-resources)) and inject `IRequestQueryStringAccessor`, which works at all depths, but filter operations are constrained to what `FilterExpression` provides
122
+
1. Implementing `IResourceDefinition.OnApplyFilter` (see [here](~/usage/extensibility/resource-definitions.md#change-filters)) and inject `IRequestQueryStringAccessor`, which works at all depths, but filter operations are constrained to what `FilterExpression` provides
123
123
2. Implementing `IResourceDefinition.OnRegisterQueryableHandlersForQueryStringParameters` as described [here](~/usage/extensibility/resource-definitions.md#custom-query-string-parameters), which enables the full range of `IQueryable<T>` functionality, but only works on primary endpoints
124
124
3. Add an implementation of `IQueryConstraintProvider` to supply additional `FilterExpression`s, which are combined with existing filters using AND operator
125
125
4. Override `EntityFrameworkCoreRepository.ApplyQueryLayer` to adapt the `IQueryable<T>` expression just before execution
Copy file name to clipboardExpand all lines: docs/usage/resources/relationships.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ public class Person : Identifiable
29
29
30
30
## HasManyThrough
31
31
32
-
Currently, Entity Framework Core [does not support](https://github.com/aspnet/EntityFrameworkCore/issues/1368) many-to-many relationships without a join entity.
32
+
Earlier versions of Entity Framework Core (up to v5) [did not support](https://github.com/aspnet/EntityFrameworkCore/issues/1368) many-to-many relationships without a join entity.
33
33
For this reason, we have decided to fill this gap by allowing applications to declare a relationship as `HasManyThrough`.
34
34
JsonApiDotNetCore will expose this relationship to the client the same way as any other `HasMany` attribute.
35
35
However, under the covers it will use the join type and Entity Framework Core's APIs to get and set the relationship.
0 commit comments