Skip to content

Commit b51cf06

Browse files
committed
Merge branch 'release/v5.3.0'
2 parents a1016f6 + 3f346a3 commit b51cf06

25 files changed

Lines changed: 403 additions & 37 deletions

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
| :no_entry: Not supporting bulk operation by default | :white_check_mark: Up to one line of code for fully functional `BULK` `API` |
2929
| :no_entry: Controller logic can't be easily used for<br/>`gRPC` or `SignalR` | :white_check_mark: You could have the same Manager to<br/> handle `REST`, `gRPC`,and a `SignalR` simultaneously |
3030
| :no_entry: Paging and Sorting should be written for<br/>every controller separately | :white_check_mark: Paging and sorting are implemented<br/> out of the box in the uniform manner |
31+
| :no_entry: Controller method can't be easily switched on/off | :white_check_mark: It is possible to use some of `CRUD` or `BULK CRUD` methods easily (switch them off and back on from routing and `API Explorer`) |
32+
3133

3234
## Minimal example
3335

@@ -43,7 +45,7 @@ Assembly stationControllerAssembly = services.AddSimplifiedAutoController<Statio
4345
services.AddControllers().AddApplicationPart(stationControllerAssembly).AddControllersAsServices();
4446
```
4547

46-
### Key Features
48+
## Key Features
4749

4850
* :fire: `REST API Controller` with **full `CRUD`** contains ***only 20 lines*** of code (~ 10 are imports)
4951
- `GET` methods have ***built-in paging*** support;
@@ -54,7 +56,9 @@ services.AddControllers().AddApplicationPart(stationControllerAssembly).AddContr
5456
- web folders (folders from mounted devices or just local folders)
5557
- S3 AWS-compatible (tested with `Yandex Object Storage` and previously with `Cloudflare R2` and `Amazon S3`)
5658

57-
:cool: `Bulk` vs :no_good_man: Non-Bulk, `Wissance.WebApiToolkit` has Bulk out of the box:
59+
* :cool: `Bulk` vs :no_good_man: Non-Bulk, `Wissance.WebApiToolkit` has Bulk out of the box:
60+
* :hammer_and_wrench: it is possibly to switch some or even all default `CRUD` or `BULK` methods from controller by setting `AllowedOperation` attribute see [the docs](https://github.com/Wissance/WebApiToolkit/wiki/REST-Controller-method-configuration)
61+
5862

5963
![Bulk vs Non Bulk](./img/bulk_performance.png)
6064

@@ -63,14 +67,16 @@ services.AddControllers().AddApplicationPart(stationControllerAssembly).AddContr
6367

6468
:sparkles: Result : Bulk `API` is almost <span style="color:green">**~250 x faster**</span>!
6569

66-
### Additional materials (Post, articles, video)
70+
## Additional materials (Post, articles, video)
6771

6872
You could see our articles about Toolkit usage:
6973
* :writing_hand: [Medium article about v1.0.x usage]( https://medium.com/@m-ushakov/how-to-reduce-amount-of-code-when-writing-netcore-rest-api-services-28352edcfca6)
7074
* :writing_hand: [Dev.to article about v1.0.x usage]( https://dev.to/wissance/dry-your-web-api-net-core-with-our-toolkit-cbb)
7175
* :writing_hand: [One line for full CRUD Medium article](https://m-ushakov.medium.com/rest-controller-in-one-line-in-net-171f46737905)
7276

73-
### Contributors
77+
## Versions History (Releases)
78+
79+
## Contributors
7480

7581
<a href="https://github.com/Wissance/WebApiToolkit/graphs/contributors">
7682
<img src="https://contrib.rocks/image?repo=Wissance/WebApiToolkit" />
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using Wissance.WebApiToolkit.Core.Operations;
3+
4+
namespace Wissance.WebApiToolkit.Core.Attributes
5+
{
6+
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
7+
public class AllowedOperationAttribute : Attribute
8+
{
9+
public AllowedOperationAttribute(ControllerOperation operations)
10+
{
11+
Operations = operations;
12+
}
13+
14+
public ControllerOperation Operations { get; internal set; }
15+
}
16+
}

Wissance.WebApiToolkit/Wissance.WebApiToolkit.Core/Controllers/BasicBulkCrudController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ public virtual async Task<OperationResultDto<TRes[]>> BulkCreateAsync([FromBody]
1919
}
2020

2121
[HttpPut]
22-
public virtual async Task<OperationResultDto<TRes[]>> UpdateAsync([FromBody] TRes[] data)
22+
public virtual async Task<OperationResultDto<TRes[]>> BulkUpdateAsync([FromBody] TRes[] data)
2323
{
2424
OperationResultDto<TRes[]> result = await Manager.BulkUpdateAsync(data);
2525
HttpContext.Response.StatusCode = result.Status;
2626
return result;
2727
}
2828

2929
[HttpDelete]
30-
public virtual async Task DeleteAsync([FromQuery] TId[] id)
30+
public virtual async Task BulkDeleteAsync([FromQuery] TId[] id)
3131
{
3232
OperationResultDto<bool> result = await Manager.BulkDeleteAsync(id);
3333
HttpContext.Response.StatusCode = result.Status;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Reflection;
2+
using Microsoft.AspNetCore.Mvc.ApplicationModels;
3+
using Wissance.WebApiToolkit.Core.Attributes;
4+
using Wissance.WebApiToolkit.Core.Controllers;
5+
6+
namespace Wissance.WebApiToolkit.Core.Operations
7+
{
8+
public class AllowedOperationsConvention: IActionModelConvention
9+
{
10+
public void Apply(ActionModel action)
11+
{
12+
ControllerModel controller = action.Controller;
13+
AllowedOperationAttribute attr = controller.ControllerType.GetCustomAttribute<AllowedOperationAttribute>();
14+
// if there is no attribute, all operations are allowed
15+
if (attr == null)
16+
return;
17+
18+
// All these names takes from
19+
ControllerOperation operation = action.ActionMethod.Name switch
20+
{
21+
// from BasicReadController
22+
"ReadAsync" => ControllerOperation.Read,
23+
"ReadByIdAsync" => ControllerOperation.ReadOne,
24+
// from BasicCrudController
25+
"CreateAsync" => ControllerOperation.Create,
26+
"UpdateAsync" => ControllerOperation.Update,
27+
"DeleteAsync" => ControllerOperation.Delete,
28+
// from BasicBulkController
29+
"BulkCreateAsync" => ControllerOperation.BulkCreate,
30+
"BulkUpdateAsync" => ControllerOperation.BulkUpdate,
31+
"BulkDeleteAsync" => ControllerOperation.BulkDelete,
32+
_ => ControllerOperation.None
33+
};
34+
35+
// Если операция не определена или не разрешена – удаляем действие
36+
if (operation == ControllerOperation.None || !attr.Operations.HasFlag(operation))
37+
{
38+
action.ActionName = null; // убираем имя действия
39+
action.Selectors.Clear(); // удаляем все маршруты
40+
action.ApiExplorer.IsVisible = false; // скрываем из Swagger
41+
}
42+
}
43+
}
44+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
3+
namespace Wissance.WebApiToolkit.Core.Operations
4+
{
5+
[Flags]
6+
public enum ControllerOperation
7+
{
8+
None = 0,
9+
Read = 1,
10+
ReadOne = 2,
11+
Create = 4,
12+
Update = 8,
13+
Delete = 16,
14+
BulkCreate = 32,
15+
BulkUpdate = 64,
16+
BulkDelete = 128,
17+
}
18+
}

Wissance.WebApiToolkit/Wissance.WebApiToolkit.TestApp/Controllers/OrganizationController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Wissance.WebApiToolkit.TestApp.Controllers
88
{
9-
public class OrganizationController : BasicCrudController<OrganizationDto, OrganizationEntity, int, EmptyAdditionalFilters>
9+
public sealed class OrganizationController : BasicCrudController<OrganizationDto, OrganizationEntity, int, EmptyAdditionalFilters>
1010
{
1111
public OrganizationController(OrganizationManager manager)
1212
{
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Wissance.WebApiToolkit.Core.Attributes;
2+
using Wissance.WebApiToolkit.Core.Controllers;
3+
using Wissance.WebApiToolkit.Core.Data;
4+
using Wissance.WebApiToolkit.Core.Operations;
5+
using Wissance.WebApiToolkit.TestApp.Data.Entity;
6+
using Wissance.WebApiToolkit.TestApp.Dto;
7+
using Wissance.WebApiToolkit.TestApp.Managers;
8+
9+
namespace Wissance.WebApiToolkit.TestApp.Controllers
10+
{
11+
[AllowedOperation(ControllerOperation.Read | ControllerOperation.ReadOne |
12+
ControllerOperation.Create | ControllerOperation.Update)]
13+
public sealed class ProfileController : BasicCrudController<ProfileDto, ProfileEntity, int, EmptyAdditionalFilters>
14+
{
15+
public ProfileController(ProfileManager manager)
16+
{
17+
Manager = manager;
18+
}
19+
}
20+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
2+
3+
namespace Wissance.WebApiToolkit.TestApp.Data.Entity.Mapping
4+
{
5+
internal static class ProfileMapper
6+
{
7+
public static void Map(this EntityTypeBuilder<ProfileEntity> builder)
8+
{
9+
builder.HasKey(p => p.Id);
10+
builder.HasOne(p => p.User).WithOne(p => p.Profile)
11+
.HasForeignKey<ProfileEntity>(p => p.UserId);
12+
}
13+
}
14+
}

Wissance.WebApiToolkit/Wissance.WebApiToolkit.TestApp/Data/Entity/Mapping/UserMapper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public static void Map(this EntityTypeBuilder<UserEntity> builder)
1010
builder.HasKey(p => p.Id);
1111
builder.HasMany(p => p.Roles)
1212
.WithMany(p => p.Users);
13+
//builder.HasOne(p => p.Profile).WithOne(p => p.User);
1314
}
1415
}
1516
}
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1+
using Wissance.WebApiToolkit.Data.Entity;
2+
13
namespace Wissance.WebApiToolkit.TestApp.Data.Entity
24
{
3-
public class ProfileEntity
5+
public class ProfileEntity : IModelIdentifiable<int>
46
{
5-
7+
public int Id { get; set; }
8+
public string Name { get; set; }
9+
public string Bio { get; set; }
10+
public string Photo { get; set; }
11+
public string Address { get; set; }
12+
13+
public int UserId { get; set; }
14+
public virtual UserEntity User { get; set; }
615
}
716
}

0 commit comments

Comments
 (0)