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
Auto-generated JSON:API controllers using source generators (#1117)
* Removed Interface target from custom attributes, because it does not work (see https://stackoverflow.com/questions/540749/can-a-c-sharp-class-inherit-attributes-from-its-interface). Fixed detection of attribute usage on base classes.
* Auto-generation of JSON:API controllers (using source generators)
* Updated integration tests to use auto-generated controllers
* Fixed: throw at startup when multiple controllers are registered for the same resource type
* Addressed cleanupcode/inspectcode issues
* Add dependency from JsonApiDotNetCore to SourceGenerators, so it gets pulled in via NuGet
* Added unit tests for controller source generator
* Update ROADMAP.md
* Updated documentation
* Produce NuGet package in cibuild
This lets each project opt-in for producing a NuGet package, instead of listing them globally
* Addressed review feedback
-[ ] Support .NET 6 with EF Core 6 [#1109](https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/1109)
28
29
29
30
Aside from the list above, we have interest in the following topics. It's too soon yet to decide whether they'll make it into v5.x or in a later major version.
Copy file name to clipboardExpand all lines: docs/usage/extensibility/controllers.md
+95-24Lines changed: 95 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,99 @@
1
1
# Controllers
2
2
3
-
You need to create controllers that inherit from `JsonApiController<TResource, TId>`
3
+
To expose API endpoints, ASP.NET controllers need to be defined.
4
+
5
+
_since v5_
6
+
7
+
Controllers are auto-generated (using [source generators](https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview)) when you add `[Resource]` on your model class:
8
+
9
+
```c#
10
+
[Resource] // Generates ArticlesController.g.cs
11
+
publicclassArticle : Identifiable<Guid>
12
+
{
13
+
// ...
14
+
}
15
+
```
16
+
17
+
## Resource Access Control
18
+
19
+
It is often desirable to limit which endpoints are exposed on your controller.
Instead of passing a set of endpoints, you can use `JsonApiEndpoints.Query` to generate all read-only endpoints or `JsonApiEndpoints.Command` for all write-only endpoints.
32
+
33
+
When an endpoint is blocked, an HTTP 403 Forbidden response is returned.
34
+
35
+
```http
36
+
DELETE http://localhost:14140/articles/1 HTTP/1.1
37
+
```
38
+
39
+
```json
40
+
{
41
+
"links": {
42
+
"self": "/articles"
43
+
},
44
+
"errors": [
45
+
{
46
+
"id": "dde7f219-2274-4473-97ef-baac3e7c1487",
47
+
"status": "403",
48
+
"title": "The requested endpoint is not accessible.",
49
+
"detail": "Endpoint '/articles/1' is not accessible for DELETE requests."
50
+
}
51
+
]
52
+
}
53
+
```
54
+
55
+
## Augmenting controllers
56
+
57
+
Auto-generated controllers can easily be augmented because they are partial classes. For example:
@@ -15,7 +108,7 @@ public class ArticlesController : JsonApiController<Article, Guid>
15
108
16
109
If you want to setup routes yourself, you can instead inherit from `BaseJsonApiController<TResource, TId>` and override its methods with your own `[HttpGet]`, `[HttpHead]`, `[HttpPost]`, `[HttpPatch]` and `[HttpDelete]` attributes added on them. Don't forget to add `[FromBody]` on parameters where needed.
17
110
18
-
## Resource Access Control
111
+
###Resource Access Control
19
112
20
113
It is often desirable to limit which routes are exposed on your controller.
21
114
@@ -37,25 +130,3 @@ public class ReportsController : JsonApiController<Report, int>
37
130
```
38
131
39
132
For more information about resource service injection, see [Replacing injected services](~/usage/extensibility/layer-overview.md#replacing-injected-services) and [Resource Services](~/usage/extensibility/services.md).
40
-
41
-
When a route is blocked, an HTTP 403 Forbidden response is returned.
42
-
43
-
```http
44
-
DELETE http://localhost:14140/people/1 HTTP/1.1
45
-
```
46
-
47
-
```json
48
-
{
49
-
"links": {
50
-
"self": "/api/v1/people"
51
-
},
52
-
"errors": [
53
-
{
54
-
"id": "dde7f219-2274-4473-97ef-baac3e7c1487",
55
-
"status": "403",
56
-
"title": "The requested endpoint is not accessible.",
57
-
"detail": "Endpoint '/people/1' is not accessible for DELETE requests."
Copy file name to clipboardExpand all lines: docs/usage/extensibility/services.md
+15-3Lines changed: 15 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,8 @@
1
1
# Resource Services
2
2
3
3
The `IResourceService` acts as a service layer between the controller and the data access layer.
4
-
This allows you to customize it however you want. This is also a good place to implement custom business logic.
4
+
This allows you to customize it however you want. While this is still a potential place to implement custom business logic,
5
+
since v4, [Resource Definitions](~/usage/extensibility/resource-definitions.md) are more suitable for that.
5
6
6
7
## Supplementing Default Behavior
7
8
@@ -77,7 +78,7 @@ public class ProductService : IResourceService<Product, int>
77
78
78
79
## Limited Requirements
79
80
80
-
In some cases it may be necessary to only expose a few methods on a resource. For this reason, we have created a hierarchy of service interfaces that can be used to get the exact implementation you require.
81
+
In some cases it may be necessary to only expose a few actions on a resource. For this reason, we have created a hierarchy of service interfaces that can be used to get the exact implementation you require.
81
82
82
83
This interface hierarchy is defined by this tree structure.
83
84
@@ -152,7 +153,18 @@ public class Startup
152
153
}
153
154
```
154
155
155
-
Then in the controller, you should inherit from the JSON:API controller and pass the services into the named, optional base parameters:
156
+
Then on your model, pass in the set of endpoints to expose (the ones that you've registered services for):
157
+
158
+
```c#
159
+
[Resource(GenerateControllerEndpoints=
160
+
JsonApiEndpoints.Create|JsonApiEndpoints.Delete)]
161
+
publicclassArticle : Identifiable<int>
162
+
{
163
+
// ...
164
+
}
165
+
```
166
+
167
+
Alternatively, when using a hand-written controller, you should inherit from the JSON:API controller and pass the services into the named, optional base parameters:
0 commit comments