I am experimenting with the abp CrudAppService (https://docs.abp.io/en/abp/latest/Application-Services#crud-application-services), which allows me to set up CRUD endpoints with minimal code.
As an example, I can create the following base class:
public class BaseAsyncCrudAppService<TEntity, TDto> : AsyncCrudAppService<TEntity, TDto, Guid, PagedAndSortedResultRequestDto,
TDto, TDto> where TEntity : class, IEntity<Guid> where TDto : IEntityDto<Guid>
{
public BaseAsyncCrudAppService(IRepository<TEntity, Guid> repository)
: base(repository)
{
}
}
And then create enpoint sets like these:
public class MyFooAppService : BaseAsyncCrudAppService<MyFooEntity, MyFooDto>,
IMyFooAppService
{
public MyFooAppService(IRepository<MyFooEntity, Guid> repository) : base(repository)
{
}
}
And
public class MyBarAppService : BaseAsyncCrudAppService<MyBarEntity, MyBarDto>,
IMyBarAppService
{
public MyBarAppService(IRepository<MyBarEntity, Guid> repository) : base(repository)
{
}
}
This will produce the following endpoints:
GET /api/services/app/MyFoo/Get
GET /api/services/app/MyFoo/GetAll
POST /api/services/app/MyFoo/Create
PUT /api/services/app/MyFoo/Update
DELETE /api/services/app/MyFoo/Delete
GET /api/services/app/MyBar/Get
GET /api/services/app/MyBar/GetAll
POST /api/services/app/MyBar/Create
PUT /api/services/app/MyBar/Update
DELETE /api/services/app/MyBar/Delete
What I would like to know is how I could alter the path where these endpoints get served. I don't need to do it individually for each method, but I would like to set it for example
GET /api/services/app/baz/MyFoo/Get
GET /api/services/app/baz/MyFoo/GetAll
POST /api/services/app/baz/MyFoo/Create
PUT /api/services/app/baz/MyFoo/Update
DELETE /api/services/baz/app/MyFoo/Delete
If were to code the endpoints manually, I would do it like this:
[Route("api/services/app/baz/[controller]/Get")]
public async Task GetMyFoo(Guid id)
{
...
}
Is there a way to do this on class level on the MyFooAppService
class?
Decorate the base class with Microsoft.AspNetCore.Mvc.Route attribute, e.g. [Route("/api/services/app/baz/[controller]")]
.
[Route("/api/services/app/baz/[controller]")]
public class BaseAsyncCrudAppService<TEntity, TDto> : AsyncCrudAppService<TEntity, TDto, Guid, PagedAndSortedResultRequestDto,
TDto, TDto> where TEntity : class, IEntity<Guid> where TDto : IEntityDto<Guid>
{
public BaseAsyncCrudAppService(IRepository<TEntity, Guid> repository)
: base(repository)
{
}
}
To customize the routes of the individual endpoints, you can override the methods and decorate them with HTTP verb attributes,
For example, [HttpGet("/new/root/here")]
[HttpGet("/new/root/here")]
public override Task<TDto> GetAsync(EntityDto<Guid> id)
{
return base.GetAsync(id);
}
would produce endpoint
GET /new/root/here/
To extend the route specified on class level, omit the leading '/'.
For example
[HttpGet("sub/root/here/")]
would make the endpoint available at
GET /api/services/app/baz/[controller]/sub/root/here/