RESTworld.EntityFrameworkCore
1.0.1
See the version list below for details.
dotnet add package RESTworld.EntityFrameworkCore --version 1.0.1
NuGet\Install-Package RESTworld.EntityFrameworkCore -Version 1.0.1
<PackageReference Include="RESTworld.EntityFrameworkCore" Version="1.0.1" />
paket add RESTworld.EntityFrameworkCore --version 1.0.1
#r "nuget: RESTworld.EntityFrameworkCore, 1.0.1"
// Install RESTworld.EntityFrameworkCore as a Cake Addin #addin nuget:?package=RESTworld.EntityFrameworkCore&version=1.0.1 // Install RESTworld.EntityFrameworkCore as a Cake Tool #tool nuget:?package=RESTworld.EntityFrameworkCore&version=1.0.1
RESTworld
RESTworld is a framework which utilizes other common frameworks and patterns alltogether to enable easy and fast creation of a truly RESTful API.
Used frameworks and patterns
- Entity Framework Core for data access
- ASP.Net Core for hosting
- HAL for providing hyperlinks between resources
- OData for query support on list endpoints
- AutoMapper for mapping between Entities and DTOs
- Resource based authorization
Pipeline
The most basic pipeline has the following data flow for a request on a list endpoint:
- Request
- Controller selection through ASP.Net Core
- Query parsing through OData
- Controller method calls business service method
- Authorization validates and modifies the request (both optional)
- Service gets the data through Entity Framework Core
- Entity Framework Core translates the query into SQL and gets the data from the database
- Business service translates Entities into DTOs through Automapper
- Authorization validates and modifies the response (both optional)
- Controller wraps the result in a HAL response
- Result
Usage
Solution structure
If your API gets the name MyApi, structure your Solution with the following Projects:
- MyApi (ASP.Net Core Web API)
- References RESTworld.AspNetCore, MyApi.Business
- Contains your startup logic and your custom controllers
- MyApi.Business
- References RESTworld.Business, MyApi.Data
- Contains your AutoMapperConfiguration and your custom services
- MyApi.Data
- References RESTworld.EntityFrameworkCore, MyApi.Common
- Contains your Entity Framework Core Database Model including Entities and Migrations
- MyApi.Common
- References RESTworld.Common
- Contains your DTOs and Enums
Startup configuration
Add the following to your appsettings.json
"RESTworld": {
"MaxNumberForListEndpoint": <whatever is an appropriate number of resources for one page>
}
Change your Program.cs to the following
namespace MyApi
{
public class Program
{
public static void Main(string[] args)
{
RESTworld.AspNetCore.Program<Startup>.Main(args);
}
}
}
Change or add your Startup class
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using RESTworld.Business.Abstractions;
using MyApi.Common.Dtos;
using MyApi.Data;
using MyApi.Data.Models;
using MyApi.Business;
namespace MyApi
{
public class Startup : RESTworld.AspNetCore.StartupBase
{
public Startup(IConfiguration configuration)
: base(configuration)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
base.Configure(app, env);
// Optionally migrate your database to the latest version during startup
MigrateDatabase<TDbContext>(app);
}
// This method gets called by the runtime. Use this method to add services to the container.
public override void ConfigureServices(IServiceCollection services)
{
// Database
services.AddDbContextFactoryWithDefaults<MyDatabase>(Configuration);
services.AddODataModelForDbContext<MyDatabase>();
// Default pipeline
services.AddRestPipeline<TContext, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto>();
// With custom service
services.AddRestPipelineWithCustomService<TContext, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto, TService>();
// Custom controllers will automatically be picked up by the pipeline so there is no need to register them.
base.ConfigureServices(services);
}
protected override void ConfigureAutomapper(IMapperConfigurationExpression config)
=> new AutoMapperConfiguration().ConfigureAutomapper(config);
}
}
Automapper
Add an AutoMapperConfiguration to your MyApi.Business project
using AutoMapper;
using MyApi.Common.Dtos;
using MyApi.Common.Enums;
using MyApi.Data.Models;
namespace MyApi.Business
{
public class AutoMapperConfiguration
{
public void ConfigureAutomapper(IMapperConfigurationExpression config)
{
config.CreateMap<TEntity, TDto>();
// Add more mappings
}
}
}
Authorization
If you want to use the inbuilt authorization logic, you must implement the interface ICrudAuthorizationHandler<TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto>
in a class to handle your own authorization logic. You can then register it in the ConfigureServices
method in your startup class.
// Concrete implementation for one service
services.AddAuthorizationHandler<MyAuthorizationHandler, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto>();
// Generic implementation which can be used for all services
services.AddAuthorizationHandler<MyGenericAuthorizationHandler<TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto>, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto>();
// Register a pipeline together with concrete authorization handler
services.AddRestPipelineWithAuthorization<TContext, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto, MyAuthorizationHandler>();
// Register a pipeline together with generic authorization handler
services.AddRestPipelineWithAuthorization<TContext, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto, MyGenericAuthorizationHandler<TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto>>();
// With a custom service implementation and concrete authorization handler
services.AddRestPipelineWithCustomServiceAndAuthorization<TContext, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto, TService, MyAuthorizationHandler>();
// With a custom service implementation and generic authorization handler
services.AddRestPipelineWithCustomServiceAndAuthorization<TContext, TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto, TService, MyGenericAuthorizationHandler<TEntity, TCreateDto, TGetListDto, TGetFullDto, TUpdateDto>>();
To get the current user, an IUserAccessor
is provided, which you may want to inject into your authorization handler implementation. It is automatically populated from the HttpContext
. However no method is provided to read the user from a token, a cookie, or something else as libraries for that are already existing. In addition no login functionality is provided, as RESTworld is meant to be a framework for APIs and the API itself should relay the login functionality to any login service (like an OAuth service or something else).
That's it. Now you can start your API and use a HAL browser like https://chatty42.herokuapp.com/hal-explorer/index.html#uri=https://localhost:5001 to browse your API.
If you are using a launchSettings.json
, I suggest to use this as your "launchUrl"
.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net5.0
- Microsoft.EntityFrameworkCore.SqlServer (>= 5.0.4)
- RESTworld.Common (>= 1.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on RESTworld.EntityFrameworkCore:
Package | Downloads |
---|---|
RESTworld.Business
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
7.2.1 | 356 | 10/11/2024 |
7.2.0 | 185 | 9/27/2024 |
7.1.4 | 123 | 9/20/2024 |
7.1.3 | 406 | 7/10/2024 |
7.1.2 | 177 | 6/4/2024 |
7.1.1 | 785 | 1/9/2024 |
7.1.0 | 223 | 12/22/2023 |
7.0.0 | 775 | 11/15/2023 |
6.1.0 | 354 | 10/23/2023 |
6.0.0 | 350 | 9/27/2023 |
5.3.2 | 291 | 9/11/2023 |
5.3.1 | 460 | 7/17/2023 |
5.3.0 | 305 | 7/3/2023 |
5.2.3 | 243 | 6/28/2023 |
5.2.2 | 956 | 6/14/2023 |
5.2.1 | 417 | 5/25/2023 |
5.2.0 | 439 | 4/30/2023 |
5.1.3 | 288 | 4/19/2023 |
5.1.2 | 329 | 3/12/2023 |
5.1.1 | 656 | 2/22/2023 |
5.1.0 | 358 | 2/9/2023 |
5.0.0 | 546 | 1/24/2023 |
4.0.1 | 773 | 12/21/2022 |
4.0.0 | 1,098 | 11/9/2022 |
3.4.2 | 946 | 10/20/2022 |
3.4.1 | 863 | 10/20/2022 |
3.4.0 | 987 | 9/27/2022 |
3.2.3 | 1,243 | 6/28/2022 |
3.2.2 | 1,845 | 6/8/2022 |
3.2.1 | 1,380 | 5/13/2022 |
3.2.0 | 1,201 | 4/1/2022 |
3.1.0 | 928 | 3/30/2022 |
3.0.2 | 1,809 | 3/10/2022 |
3.0.1 | 1,289 | 3/9/2022 |
3.0.0 | 3,241 | 2/21/2022 |
2.0.2 | 857 | 1/14/2022 |
2.0.1 | 481 | 1/6/2022 |
2.0.0 | 905 | 12/3/2021 |
1.3.1 | 1,054 | 11/4/2021 |
1.3.0 | 1,963 | 9/29/2021 |
1.2.0 | 629 | 9/27/2021 |
1.1.0 | 1,105 | 8/18/2021 |
1.0.3 | 899 | 6/29/2021 |
1.0.2 | 558 | 5/11/2021 |
1.0.1 | 583 | 4/22/2021 |
1.0.0 | 905 | 3/31/2021 |