Skip to content

Write enhancements (continued) #875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 65 commits into from
Nov 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
cd5ea5a
Enhancements in create/update/delete
Nov 5, 2020
abef99e
Various cleanups based on diff with master.
Nov 5, 2020
a373127
refactor: reduced ResourceService dependencies
Nov 5, 2020
0d90ee3
refactor: move logic from GetResourcesByIds to composer
Nov 5, 2020
a2a6789
Refactor: remove IGetResourcesByIds
Nov 5, 2020
1c7cf6a
Replace repo.GetPrimaryResourceForCompleteReplacement with overridabl…
Nov 5, 2020
5dc95bb
Removed IDataStoreUpdateFailureInspector dependency from repository
Nov 5, 2020
25e109c
Simplified code
Nov 5, 2020
cede530
More refactorings
Nov 6, 2020
ba47b8e
Added services.AddResourceRepository()
Nov 6, 2020
9ff1c88
removed TODO
Nov 6, 2020
26b7ea4
Reorder methods in calling order, renames, expose FlushFromCache/Save…
Nov 6, 2020
6ac48be
Removed ThroughEntitiesFilter
Nov 6, 2020
cd57383
Renames
Nov 6, 2020
5b8b947
Extract responsibilities
Nov 6, 2020
9f675d0
Added tracking TODOs
Nov 6, 2020
6ff1b51
formatting
Nov 6, 2020
b092686
TODO
Nov 6, 2020
ddfad48
Added tests for obfuscated IDs
Nov 6, 2020
6da677e
Added marker to our TODOs
Nov 6, 2020
ac6611d
Added documentation
Nov 6, 2020
beaec67
Tests for cyclic relationships
Nov 10, 2020
5929957
Folder rename
Nov 10, 2020
7b8f44b
Migrated left-over tests
Nov 10, 2020
0270fbf
Change casing of .sln (1/2)
Nov 10, 2020
aeb569f
Change casing of .sln (2/2)
Nov 10, 2020
c28b137
chore: restore toplevel related links in relationship endpoint
maurei Nov 11, 2020
4f95499
Merged IntegrationTests project
Nov 11, 2020
2fb771f
Added tests for 0 or empty string as primary key value
Nov 11, 2020
b8abc93
Removed TODO
Nov 11, 2020
ec72f99
tests: pagination on relationship endpoint
maurei Nov 11, 2020
f7d341a
Fixes and more tests for handling zero/empty primary key
Nov 11, 2020
700653d
Merge branch 'write-enhancements' of https://github.com/json-api-dotn…
Nov 11, 2020
d7010db
added check for related link
Nov 11, 2020
4150447
Fixes for proper error on relationship kind mismatch (HasOne vs HasMany)
Nov 11, 2020
163a5f6
Removed empty folder
Nov 12, 2020
e791c8d
tests: added required relationship tests, changed existing tests to d…
maurei Nov 12, 2020
6d83191
Improved purging of change tracker
Nov 12, 2020
85bbf49
Replaced dependency on IResourceRepository with IResourceRepositoryAc…
Nov 13, 2020
d92c707
Move logic around to reduce dependencies in SecondaryResourceResolver.
Nov 13, 2020
6ad09ea
Inlined ISecondaryResourceResolver into JsonApiResourceService
Nov 13, 2020
e1bf9e0
Refactorings to remove joinTableFilter parameter from ResourceReposit…
Nov 13, 2020
8ae75b6
Do not fetch resource for hooks on delete (because we didn't do that …
Nov 13, 2020
a1730ab
Merge branch 'master' into write-enhancements
Nov 13, 2020
1181245
tests: required relationships
maurei Nov 14, 2020
81dcdd3
feat: throw CannotClearRequiredRelationshipException
maurei Nov 14, 2020
7c60e4c
chore: self review
maurei Nov 14, 2020
227b353
merge
maurei Nov 14, 2020
9699456
refactor: EF Core null assignment change tracker trick no longer requ…
maurei Nov 16, 2020
1f98946
refactorings
Nov 16, 2020
170a0ac
refactorings
Nov 16, 2020
653fa88
Added ID to error message
Nov 16, 2020
d8f011d
chore: review todos
maurei Nov 16, 2020
a296724
Remove unused usings
Nov 16, 2020
9ed55c3
merge, add required relationship default behavior relationship endpoi…
maurei Nov 16, 2020
c5d56cd
Merge branch 'write-enhancements' of https://github.com/json-api-dotn…
maurei Nov 16, 2020
df5f776
fix: minor refactor repository
maurei Nov 16, 2020
9ee05c4
review
Nov 16, 2020
b3a1c2c
removed query for jointable
Nov 16, 2020
0f45d72
fix name
Nov 16, 2020
dc98ae4
Use generic type parameter in IResourceRepositoryAccessor
Nov 16, 2020
3ce41bd
Expose EntityFrameworkCoreRepository methods as protected to enable c…
Nov 16, 2020
012eef8
Readme updates
Nov 16, 2020
9ad1b9e
Small tweaks based on diff with master
Nov 16, 2020
722021e
Fixed casing
Nov 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
461 changes: 223 additions & 238 deletions JsonApiDotnetCore.sln → JsonApiDotNetCore.sln

Large diffs are not rendered by default.

48 changes: 21 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src ="https://raw.githubusercontent.com/json-api-dotnet/JsonApiDotnetCore/master/logo.png" />
</p>

# JSON API .Net Core
# JSON:API .NET Core

[![Build status](https://ci.appveyor.com/api/projects/status/5go47hrm0iik0ls3/branch/master?svg=true)](https://ci.appveyor.com/project/jaredcnance/jsonapidotnetcore/branch/master)
[![Travis](https://travis-ci.org/json-api-dotnet/JsonApiDotNetCore.svg?branch=master)](https://travis-ci.org/json-api-dotnet/JsonApiDotNetCore)
Expand All @@ -21,7 +21,7 @@ These are some steps you can take to help you understand what this project is an
- [Demo [Video]](https://youtu.be/KAMuo6K7VcE)
- [Our documentation](https://json-api-dotnet.github.io/JsonApiDotNetCore/)
- [Check out the example projects](https://github.com/json-api-dotnet/JsonApiDotNetCore/tree/master/src/Examples)
- [Embercasts: Full Stack Ember with ASP .NET Core](https://www.embercasts.com/course/full-stack-ember-with-dotnet/watch/whats-in-this-course-cs)
- [Embercasts: Full Stack Ember with ASP.NET Core](https://www.embercasts.com/course/full-stack-ember-with-dotnet/watch/whats-in-this-course-cs)

## Related Projects

Expand All @@ -43,7 +43,7 @@ See [our documentation](https://json-api-dotnet.github.io/JsonApiDotNetCore/) fo
```csharp
public class Article : Identifiable
{
[Attr("name")]
[Attr]
public string Name { get; set; }
}
```
Expand All @@ -53,12 +53,11 @@ public class Article : Identifiable
```csharp
public class ArticlesController : JsonApiController<Article>
{
public ArticlesController(
IJsonApiOptions options,
IResourceService<Article> resourceService,
ILoggerFactory loggerFactory)
: base(options, resourceService, loggerFactory)
{ }
public ArticlesController(IJsonApiOptions options, IResourceService<Article> resourceService,
ILoggerFactory loggerFactory)
: base(options, resourceService, loggerFactory)
{
}
}
```

Expand All @@ -67,14 +66,16 @@ public class ArticlesController : JsonApiController<Article>
```csharp
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services) {
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddJsonApi<AppDbContext>();
// ...
}

public void Configure(IApplicationBuilder app) {
app.UseJsonApi()
// ...
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseJsonApi();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
}
```
Expand All @@ -101,26 +102,19 @@ And then to run the tests:
dotnet test
```

#### Cleaning

Sometimes the compiled files can be dirty / corrupt from other branches / failed builds.

```bash
dotnet clean
```

#### Compiler warnings

The `Release` build configuration is set to fail on warnings. That means when submitting a PR there shouldn't be any compiler warnings because the CI build it set to `Release`.

## Compatibility

A lot of changes were introduced in v4.0.0, the following chart should help you with compatibility issues between .NET Core versions
A lot of changes were introduced in v4, the following chart should help you with compatibility issues between .NET Core versions.

| .NET Core Version | JADNC Version |
| ----------------- | ------------- |
| 2.* | v3.* |
| 3.* | v4.* |
| .NET Core Version | EF Core Version | JADNC Version |
| ----------------- | --------------- | ------------- |
| 2.x | 2.x | v3.x |
| 3.x | 3.x, 5.x | v4.x |
| 5.x | 5.x | v4.x |

## Trying out the latest build

Expand Down
4 changes: 3 additions & 1 deletion benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.ComponentModel.Design;
using BenchmarkDotNet.Attributes;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Middleware;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.Serialization;
using JsonApiDotNetCore.Serialization.Objects;
Expand Down Expand Up @@ -37,7 +38,8 @@ public JsonApiDeserializerBenchmarks()
var options = new JsonApiOptions();
IResourceGraph resourceGraph = DependencyFactory.CreateResourceGraph(options);
var targetedFields = new TargetedFields();
_jsonApiDeserializer = new RequestDeserializer(resourceGraph, new ResourceFactory(new ServiceContainer()), targetedFields, new HttpContextAccessor());
var request = new JsonApiRequest();
_jsonApiDeserializer = new RequestDeserializer(resourceGraph, new ResourceFactory(new ServiceContainer()), targetedFields, new HttpContextAccessor(), request);
}

[Benchmark]
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Serialization/JsonApiSerializerBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private static FieldsToSerialize CreateFieldsToSerialize(IResourceGraph resource

var accessor = new Mock<IResourceDefinitionAccessor>().Object;

return new FieldsToSerialize(resourceGraph, constraintProviders, accessor);
return new FieldsToSerialize(resourceGraph, constraintProviders, accessor, request);
}

[Benchmark]
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Install-Package JsonApiDotnetCore
```xml
<ItemGroup>
<!-- Be sure to check NuGet for the latest version # -->
<PackageReference Include="JsonApiDotNetCore" Version="3.0.0" />
<PackageReference Include="JsonApiDotNetCore" Version="4.0.0" />
</ItemGroup>
```
2 changes: 1 addition & 1 deletion docs/internals/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Internals

The section contains overviews for the inner workings of the JsonApiDotNetCore library.
This section contains overviews for the inner workings of the JsonApiDotNetCore library.
8 changes: 4 additions & 4 deletions docs/request-examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,22 @@ _Note that cURL requires "[" and "]" in URLs to be escaped._

# Writing data

### Create
### Create resource

[!code-ps[REQUEST](010_CREATE_Person.ps1)]
[!code-json[RESPONSE](010_CREATE_Person_Response.json)]

### Create with relationship
### Create resource with relationship

[!code-ps[REQUEST](011_CREATE_Book-with-Author.ps1)]
[!code-json[RESPONSE](011_CREATE_Book-with-Author_Response.json)]

### Update
### Update resource

[!code-ps[REQUEST](012_PATCH_Book.ps1)]
[!code-json[RESPONSE](012_PATCH_Book_Response.json)]

### Delete
### Delete resource

[!code-ps[REQUEST](013_DELETE_Book.ps1)]
[!code-json[RESPONSE](013_DELETE_Book_Response.json)]
17 changes: 16 additions & 1 deletion docs/usage/extensibility/repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
If you want to use a data access technology other than Entity Framework Core, you can create an implementation of `IResourceRepository<TResource, TId>`.
If you only need minor changes you can override the methods defined in `EntityFrameworkCoreRepository<TResource, TId>`.

The repository should then be added to the service collection in Startup.cs.
The repository should then be registered in Startup.cs.

```c#
public void ConfigureServices(IServiceCollection services)
Expand All @@ -12,6 +12,21 @@ public void ConfigureServices(IServiceCollection services)
}
```

In v4.0 we introduced an extension method that you can use to register a resource repository on all of its JsonApiDotNetCore interfaces.
This is helpful when you implement a subset of the resource interfaces and want to register them all in one go.

Note: If you're using service discovery, this happens automatically.

```c#
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddResourceRepository<ArticleRepository>();
}
}
```

A sample implementation that performs authorization might look like this.

All of the methods in EntityFrameworkCoreRepository will use the `GetAll()` method to get the `DbSet<TResource>`, so this is a good method to apply filters such as user or tenant authorization.
Expand Down
4 changes: 3 additions & 1 deletion docs/usage/extensibility/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ IResourceService
PATCH /{id}/relationships/{relationship}
```

In order to take advantage of these interfaces you first need to inject the service for each implemented interface.
In order to take advantage of these interfaces you first need to register the service for each implemented interface.

```c#
public class ArticleService : ICreateService<Article>, IDeleteService<Article>
Expand All @@ -136,6 +136,8 @@ public class Startup
In v3.0 we introduced an extension method that you can use to register a resource service on all of its JsonApiDotNetCore interfaces.
This is helpful when you implement a subset of the resource interfaces and want to register them all in one go.

Note: If you're using service discovery, this happens automatically.

```c#
public class Startup
{
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ GET /articles/1?include=comments HTTP/1.1

## Nested Inclusions

_since v3.0.0_
_since v3_

JsonApiDotNetCore also supports nested inclusions.
This allows you to include data across relationships by using a period-delimited relationship path, for example:
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/usage/resource-graph.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The Resource Graph

_NOTE: prior to 3.0.0 this was called the `ContextGraph`_
_NOTE: prior to v4 this was called the `ContextGraph`_

The `ResourceGraph` is a map of all the json:api resources and their relationships that your API serves.

Expand Down
3 changes: 0 additions & 3 deletions docs/usage/resources/relationships.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ public class TodoItem : Identifiable<int>
}
```

The convention used to locate the foreign key property (e.g. `OwnerId`) can be changed on
the @JsonApiDotNetCore.Configuration.JsonApiOptions#JsonApiDotNetCore_Configuration_JsonApiOptions_RelatedIdMapper

## HasMany

```c#
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/resources/resource-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public class EmployeeDefinition : JsonApiResourceDefinition<Employee>

## Custom query string parameters

_since v3.0.0_
_since v3_

You can define additional query string parameters with the LINQ expression that should be used.
If the key is present in a query string, the supplied LINQ expression will be added to the database query.
Expand Down
17 changes: 12 additions & 5 deletions docs/usage/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
## [Relationships](resources/relationships.md)
## [Resource Definitions](resources/resource-definitions.md)

# Reading data
## [Filtering](reading/filtering.md)
## [Sorting](reading/sorting.md)
## [Pagination](reading/pagination.md)
## [Sparse Fieldset Selection](reading/sparse-fieldset-selection.md)
## [Including Relationships](reading/including-relationships.md)

# Writing data
## [Creating](writing/creating.md)
## [Updating](writing/updating.md)
## [Deleting](writing/deleting.md)

# [Resource Graph](resource-graph.md)
# [Options](options.md)
# [Filtering](filtering.md)
# [Sorting](sorting.md)
# [Pagination](pagination.md)
# [Sparse Fieldset Selection](sparse-fieldset-selection.md)
# [Including Relationships](including-relationships.md)
# [Routing](routing.md)
# [Errors](errors.md)
# [Metadata](meta.md)
Expand Down
74 changes: 74 additions & 0 deletions docs/usage/writing/creating.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Creating resources

A single resource can be created by sending a POST request. The next example creates a new article:

```http
POST /articles HTTP/1.1

{
"data": {
"type": "articles",
"attributes": {
"caption": "A new article!",
"url": "www.website.com"
}
}
}
```

When using client-generated IDs and only attributes from the request have changed, the server returns `204 No Content`.
Otherwise, the server returns `200 OK`, along with the updated resource and its newly assigned ID.

In both cases, a `Location` header is returned that contains the URL to the new resource.

# Creating resources with relationships

It is possible to create a new resource and establish relationships to existing resources in a single request.
The example below creates an article and sets both its owner and tags.

```http
POST /articles HTTP/1.1

{
"data": {
"type": "articles",
"attributes": {
"caption": "A new article!"
},
"relationships": {
"author": {
"data": {
"type": "person",
"id": "101"
}
},
"tags": {
"data": [
{
"type": "tag",
"id": "123"
},
{
"type": "tag",
"id": "456"
}
]
}
}
}
}
```

# Response body

POST requests can be combined with query string parameters that are normally used for reading data, such as `include` and `fields`. For example:

```http
POST /articles?include=owner&fields[owner]=firstName HTTP/1.1

{
...
}
```

After the resource has been created on the server, it is re-fetched from the database using the specified query string parameters and returned to the client.
9 changes: 9 additions & 0 deletions docs/usage/writing/deleting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Deleting resources

A single resource can be deleted using a DELETE request. The next example deletes an article:

```http
DELETE /articles/1 HTTP/1.1
```

This returns `204 No Content` if the resource was successfully deleted. Alternatively, if the resource does not exist, `404 Not Found` is returned.
Loading