Skip to content

Commit 234cc86

Browse files
committed
chore: review 2
1 parent c51eea3 commit 234cc86

File tree

7 files changed

+43
-65
lines changed

7 files changed

+43
-65
lines changed

docs/usage/extensibility/middleware.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ All of these components (except for `JsonApiMiddleware`) can be customized by re
3939
services.AddSingleton<IJsonApiExceptionFilter, MyCustomExceptionFilter>();
4040
```
4141

42-
It is also possible to directly access the .NET Core `MvcOptions` object and have full controll over which components are registered.
42+
It is also possible to directly access the .NET Core `MvcOptions` object and have full control over which components are registered.
4343

4444
## Configuring MvcOptions
4545

46-
JsonApiDotNetCore internally configures `MvcOptions` when calling `AddJsonApi( ... )`. However, it is still possible to register a custom configuration callback. To achieve this it is recommended to register this callback *after* the `AddJsonApi( ... )` call. It is also possible to do it earlier, but your configuration might be overridden by the JsonApiDotNetCore configuration.
46+
JsonApiDotNetCore internally configures `MvcOptions` when calling `AddJsonApi( ... )`. However, it is still possible to register a custom configuration callback. To achieve this it is recommended to register this callback *after* the `AddJsonApi( ... )` call. It is also possible to do it earlier, but your configuration might be overwritten by the JsonApiDotNetCore configuration.
4747

4848
The following example replaces all internally registered filters by retrieving a custom filter from the DI container.
4949
```c#
@@ -57,10 +57,10 @@ public class Startup
5757

5858
var builder = services.AddMvcCore();
5959
services.AddJsonApi<AppDbContext>( ... , mvcBuilder: builder);
60-
mvcCoreBuilder.AddMvcOptions(x =>
60+
mvcCoreBuilder.AddMvcOptions(mvcOptions =>
6161
{
62-
// execute the mvc configuration callback after the JsonApiDotNetCore callback as been executed.
63-
_postConfigureMvcOptions?.Invoke(x);
62+
// Execute the mvcOptions configuration callback after the JsonApiDotNetCore callback as been executed.
63+
_postConfigureMvcOptions?.Invoke(mvcOptions);
6464
});
6565

6666
...

docs/usage/options.md

+6
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,14 @@ options.SerializerSettings.Converters.Add(new StringEnumConverter());
9090
options.SerializerSettings.Formatting = Formatting.Indented;
9191
```
9292

93+
The default naming convention as used in the routes and public resources names is also determined here, and can be changed (default is camel-case):
94+
```c#
95+
options.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new KebabCaseNamingStrategy() };
96+
```
97+
9398
Because we copy resource properties into an intermediate object before serialization, Newtonsoft.Json annotations on properties are ignored.
9499

100+
95101
## Enable ModelState Validation
96102

97103
If you would like to use ASP.NET Core ModelState validation into your controllers when creating / updating resources, set `ValidateModelState = true`. By default, no model validation is performed.

docs/usage/resource-graph.md

+5-18
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public void ConfigureServices(IServiceCollection services)
2828
{
2929
services.AddJsonApi(resources: builder =>
3030
{
31-
builder.AddResource<Person>();
31+
builder.Add<Person>();
3232
});
3333
}
3434
```
@@ -60,7 +60,7 @@ public void ConfigureServices(IServiceCollection services)
6060
### Auto-discovery
6161

6262
Auto-discovery refers to the process of reflecting on an assembly and
63-
detecting all of the json:api resources and services.
63+
detecting all of the json:api resources, resource definitions, resource services and repositories.
6464

6565
The following command will build the resource graph using all `IIdentifiable`
6666
implementations. It also injects resource definitions and service layer overrides which we will
@@ -81,11 +81,11 @@ public void ConfigureServices(IServiceCollection services)
8181

8282
The public resource name is exposed through the `type` member in the json:api payload. This can be configured by the following approaches (in order of priority):
8383

84-
1. The `publicName` option when manually adding a resource to the graph
84+
1. The `publicName` parameter when manually adding a resource to the graph
8585
```c#
8686
services.AddJsonApi(resources: builder =>
8787
{
88-
builder.AddResource<Person>(publicName: "people");
88+
builder.Add<Person>(publicName: "people");
8989
});
9090
```
9191

@@ -100,17 +100,4 @@ public class MyModel : Identifiable { /* ... */ }
100100
// this will be registered as "myModels"
101101
public class MyModel : Identifiable { /* ... */ }
102102
```
103-
This convention can be changed by setting the `SerializerSettings` property on `IJsonApiOptions`.
104-
```c#
105-
public void ConfigureServices(IServiceCollection services)
106-
{
107-
services.AddJsonApi(
108-
options =>
109-
{
110-
options.SerializerSettings.ContractResolver = new DefaultContractResolver
111-
{
112-
NamingStrategy = new KebabCaseNamingStrategy()
113-
}
114-
});
115-
}
116-
```
103+
This convention can be changed by setting the `SerializerSettings.ContractResolver` property on `IJsonApiOptions`. See the [options documentation](./options.md#custom-serializer-settings).

docs/usage/routing.md

+27-39
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
11
# Routing
2+
3+
## Namespacing and Versioning URLs
4+
You can add a namespace to all URLs by specifying it in ConfigureServices
5+
6+
```c#
7+
public void ConfigureServices(IServiceCollection services)
8+
{
9+
services.AddJsonApi<AppDbContext>(
10+
options => options.Namespace = "api/v1");
11+
}
12+
```
13+
Which results in URLs like: https://yourdomain.com/api/v1/people
14+
15+
## Customizing Routes
16+
217
The library will configure routes for each controller. By default, based on the [recommendations](https://jsonapi.org/recommendations/) outlined in the json:api spec, routes are camel-cased.
318

419
```http
520
GET /api/compoundModels HTTP/1.1
621
```
722

8-
There are two ways the library will try to create a route for a controller:
9-
1. **By inspecting the controller for an associated resource**. The library will try to first use the public resource name of the resource associated to a controller. This means that the value of the `type` member of the json:api document for a resource will be equal to the route.
10-
Note that this implies that it is possible to configure a route configuring the exposed resource name. See [this section](~/usage/resource-graph.md#public-resource-name) on how this can be achieved. Example:
11-
```c#
12-
// controller
13-
public class MyResourceController : JsonApiController<MyApiResource> { /* .... */ } // note that the route is NOT "myResources", but "myApiResources"
23+
1. **Using the public name of the resource associated to a controller**.
1424

15-
// request
16-
GET /myApiResources HTTP/1.1
25+
```c#
26+
public class MyResourceController : JsonApiController<MyApiResource> { /* .... */ }
27+
```
28+
Note that the route
29+
- is `/myApiResources`, which matches the public resouce name in the json:api payload (`{ "type": "myApiResources", ... }`)
30+
- can be configured by configuring the public resource name. See [this section](~/usage/resource-graph.md#public-resource-name) on how to do that.
1731

18-
// response
19-
HTTP/1.1 200 OK
20-
Content-Type: application/vnd.api+json
2132

22-
{
23-
"data": [{
24-
"type": "myApiResources",
25-
"id": "1",
26-
"attributes": { ... }
27-
}]
28-
}
29-
```
30-
2. **By using the name of the controller**. If no associated resource was detected for a controller, the library will construct a route from the name of the controller by using the configured naming strategy (*camelCase* by default, see [this section](~/usage/resource-graph.md#public-resource-name) on how to configure this). This is in alignment with the default .NET Core MVC routing approach.
31-
In the following example the controller is not associated to a resource by the library because it does not inherit from `BaseJsonApiController<T>`.
33+
2. **Using the controller name**.
34+
If a controller does not have an associated resource, the name of the controller will be used following the configured naming strategy.
3235
```c#
33-
// controller
3436
public class MyResourceController : ControllerBase { /* .... */ }
35-
36-
// request
37-
GET /myResources HTTP/1.1
3837
```
38+
Note that the route is `myResources` can be changed by renaming the controller. This approach is the default .NET Core MVC routing approach.
3939

40-
## Customized the Routing Convention
41-
It is possible to fully customize routing behaviour by registering a `IJsonApiRoutingConvention` implementation.
40+
## Customizing the Routing Convention
41+
It is possible to fully customize routing behavior by registering a `IJsonApiRoutingConvention` implementation.
4242
```c#
4343
// Startup.cs
4444
public void ConfigureServices(IServiceCollection services)
@@ -47,18 +47,6 @@ public void ConfigureServices(IServiceCollection services)
4747
}
4848
```
4949

50-
## Namespacing and Versioning URLs
51-
You can add a namespace to all URLs by specifying it in ConfigureServices
52-
53-
```c#
54-
public void ConfigureServices(IServiceCollection services)
55-
{
56-
services.AddJsonApi<AppDbContext>(
57-
options => options.Namespace = "api/v1");
58-
}
59-
```
60-
Which results in URLs like: https://yourdomain.com/api/v1/people
61-
6250
## Disabling the Default Routing Convention
6351
It is possible to completely bypass the default routing convention for a particular controller and specify a custom routing template by using the `DisableRoutingConvention` attribute.
6452
In the following example, the `CamelCasedModel` resource can be accessed on `/my-custom-route`.

src/Examples/JsonApiDotNetCoreExample/Startups/EmptyStartup.cs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Microsoft.AspNetCore.Hosting;
33
using Microsoft.Extensions.Configuration;
44
using Microsoft.Extensions.DependencyInjection;
5-
using Microsoft.Extensions.Logging;
65

76
namespace JsonApiDotNetCoreExample
87
{

src/Examples/JsonApiDotNetCoreExample/Startups/TestStartup.cs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Microsoft.AspNetCore.Authentication;
33
using Microsoft.Extensions.Configuration;
44
using Microsoft.Extensions.DependencyInjection;
5-
using Microsoft.Extensions.Logging;
65

76
namespace JsonApiDotNetCoreExample
87
{

test/JsonApiDotNetCoreExampleTests/Acceptance/NonJsonApiControllerTests.cs

-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ public async Task NonJsonApiController_Skips_Middleware_And_Formatters_On_Delete
9292

9393
// Act
9494
var response = await client.SendAsync(request);
95-
var test = await response.Content.ReadAsStringAsync();
9695
// Assert
9796
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
9897
Assert.Equal("text/plain; charset=utf-8", response.Content.Headers.ContentType.ToString());

0 commit comments

Comments
 (0)