All Projects → exilon → QuickCore

exilon / QuickCore

Licence: Apache-2.0, Apache-2.0 licenses found Licenses found Apache-2.0 LICENSE Apache-2.0 LICENSE.txt
Delphi Core Framework to fast build desktop/mobile/web apps.

Programming Languages

pascal
1382 projects

Projects that are alternatives of or similar to QuickCore

Diamond
Diamond is a full-stack web-framework written in The D Programming Language using vibe.d
Stars: ✭ 173 (+105.95%)
Mutual labels:  mvc, controller
Wpemerge
A modern, MVC-powered WordPress as a CMS workflow. 🚀
Stars: ✭ 348 (+314.29%)
Mutual labels:  mvc, controller
MVVM-Design-Pattern-Demo
An Xcode 9 project written in Swift 4 code designed using the MVVM design pattern, truly extolling the virtues of MVVM over MVC.
Stars: ✭ 31 (-63.1%)
Mutual labels:  mvc, controller
Modelassistant
Elegant library to manage the interactions between view and model in Swift
Stars: ✭ 26 (-69.05%)
Mutual labels:  mvc, controller
Polyel-Framework
⚡️ Voltis Core: A PHP framework based on Swoole from the ground up
Stars: ✭ 22 (-73.81%)
Mutual labels:  mvc, controller
databind-js
A powerful and flexible MVC data binding library
Stars: ✭ 16 (-80.95%)
Mutual labels:  mvc
terraform-operator
A Kubernetes CRD to handle terraform operations
Stars: ✭ 204 (+142.86%)
Mutual labels:  controller
puremvc-swift-multicore-framework
PureMVC MultiCore Framework for Swift
Stars: ✭ 17 (-79.76%)
Mutual labels:  mvc
sirius
Modern coffeescript/javascript framework
Stars: ✭ 20 (-76.19%)
Mutual labels:  mvc
dva-boot
🌱 使用CRA(create-react-app v2) 构建的react dva 2 脚手架 支持动态路由、接口数据模拟、按功能分层、并且包含诸多实用的小组件
Stars: ✭ 79 (-5.95%)
Mutual labels:  mvc
view
Yii view rendering library
Stars: ✭ 42 (-50%)
Mutual labels:  mvc
TextFieldsTraversalController
A controller to manage the traversal of a collection of textfields.
Stars: ✭ 15 (-82.14%)
Mutual labels:  controller
docker-zerotier-controller
Dockernized ZeroTierOne Controller
Stars: ✭ 170 (+102.38%)
Mutual labels:  controller
PHP MVC LightweightFramework
【停更】PHP_MVC_API作为一个极其轻量级MVC&API开发框架,不断吸取参考了flight、phx、discuz、punbb等开源项目的优点,最终形成独具自己风格的快速开发框架。适合微小型项目,目前我主要用于服务端应用程序接口开发,提供API和移动APP进行数据交换。推荐使用https://github.com/phalapi/phalapi
Stars: ✭ 16 (-80.95%)
Mutual labels:  mvc
fluentassertions.mvc
Fluent Assertions extensions for ASP.NET MVC
Stars: ✭ 36 (-57.14%)
Mutual labels:  mvc
django-views-tutorial
🚀 ✅ Function and class-based Django view repository.
Stars: ✭ 19 (-77.38%)
Mutual labels:  mvc
dilovel
An advanced framework is written in PHP, a framework containing rich components such as middleware, orm, request management, template engine, elasticsearch, template engine, many modern frameworks have been written by adopting clean code principles completely written in accordance with PHP standards. like linux operating system ...All of control…
Stars: ✭ 38 (-54.76%)
Mutual labels:  mvc
ExpressPHP-V1
✨ ExpressPHP V1是一个极简的 web 开发MVC框架,和ThinkPHP5一样现代化,比CodeIgniter还要轻量级,真正突破框架限制,让你感受到自由,同时兼顾高性能、低学习成本。
Stars: ✭ 13 (-84.52%)
Mutual labels:  mvc
modular routes
Dedicated controllers for each of your Rails route actions.
Stars: ✭ 45 (-46.43%)
Mutual labels:  controller
wulaphp
一个有点复杂的PHP框架!
Stars: ✭ 26 (-69.05%)
Mutual labels:  mvc

alt text

Delphi Framework (Windows/Linux/Android/MACOSX/IOS) to build high-performance and scalable desktop, mobile and web applications easily.

Areas of functionality:

  • Mapping: Map fields from a class to other class, copy objects, etc..
  • Config: Easy integration of sections into config settings. Supports Json and Yaml formats.
  • Authorization: Authorization validation.
  • Serialization: Object/Array serialization to/from json/Yaml.
  • Scheduling: Schedule tasks launching as independent threads with retry policies.
  • Database: Easy entity framework to work with SQLite, MSSQL, etc
  • UserManagement:
  • Caching:: Cache string or objects to retrieve fast later.
  • MVC Web: Create own Api or MVC server to serve own site.

Give it a star

Please "star" this project in GitHub! It costs nothing but helps to reference the code. alt text

Support

If you find this project useful, please consider making a donation.

paypal

Main units description:

Abstractions:

  • Quick.Core.Logging.Abstractions: Logging service abstractions.
  • Quick.Core.Caching.Abstractions: Memory caching service abstractions.
  • Quick.Core.Mapping.Abstractions: Mapping objects service abstractions.
  • Quick.Core.Identity.Abstractions: User identity store abstractions.
  • Quick.Core.Linq.Abstractions: LinQ abstractions.
  • Quick.Core.Serialization.Abstractions: Serialization service abstractions.

Services:

  • Quick.Core.AutoMapper: Mapping objects service implementation.
  • Quick.Core.Container: Dependency injection container service.
  • Quick.Core.Entity: Entity database access service implementation.
  • Quick.Core.Identity: User Identity service implementation.
  • Quick.Core.Logging: Logging service implementation.
  • Quick.Core.Serialization: Json/Yaml Serialization service implementation.
  • Quick.Core.TaskControl: Task/Job control service implementation (not ready yet).
  • Quick.Core.Security.UserManager: User manager service implementation.
  • Quick.Core.Security.Authentication: Authentication service implementation.
  • Quick.Core.Security.Authorization: Authorization service implementation.
  • Quick.Core.Security.Claims: Authorization security claims definitions.

MVC:

  • Quick.Core.Mvc: Main Mvc core implementation.
  • Quick.Core.Mvc.Controller: Controller implementation.
  • Quick.Core.Mvc.ActionResult: Controller responses implementation.
  • Quick.Core.Mvc.ActionInvoker: Controller actions implementation.
  • Quick.Core.Mvc.Context: Http Request Context implementation.
  • Quick.Core.Mvc.Routing: Mvc routing implementation.
  • Quick.Core.Mvc.Session: User session implementation (not ready)
  • Quick.Core.MvcViewFeatures: Viewdata implementation.
  • Quick.Core.Mvc.ViewEngine.Mustache: Very basic mustache template implementation.
  • Quick.Core.Mvc.Middleware.Authentication: Authentication requests middleware.
  • Quick.Core.Mvc.Middleware.Authorization: Request Authorization validation middleware.
  • Quick.Core.Mvc.Middleware.Cache: Response caching middleware.
  • Quick.Core.Mvc.Middleware.Hsts: Http Strict Transport Security middleware.
  • Quick.Core.Mvc.Mvc: Mvc main middleware.
  • Quick.Core.Mvc.Middleware: Mvc routing middleware.
  • Quick.Core.Mvc.StaticFiles: Static files middleware.
  • Quick.Core.Mvc.HttpsRedirection: Https force redirection middleware.
  • Quick.Core.Mvc.TaskControl: Task/Job control middleware(not ready yet).

Extensions:

  • Quick.Core.Extensions.Authentication: Authentication service.
  • Quick.Core.Extensions.Authentication.ApiKey: ApiKey based Authentication.
  • Quick.Core.Extensions.Authorization: Authorization service.
  • Quick.Core.Extensions.AutoMapper: Mapping objects service.
  • Quick.Core.Extensions.Caching.Memory: Memory Cache service.
  • Quick.Core.Extensions.Caching.Redis: Redis Cache service.
  • Quick.Core.Extensions.Entity: Entity framework service.
  • Quick.Core.Extensions.Serialization: Serialization service.

Mvc Extensions:

  • Quick.Core.Mvc.Extensions.Entity.Rest: Api Rest service.
  • Quick.Core.Mvc.Extensions.ResponseCaching: Response caching service.
  • Quick.core.Mvc.Extensions.TaskControl: Task/Job control service.

Updates:

  • 11/08/2020: Added commandline extension.
  • 12/07/2020: Updated documentation.
  • 06/07/2020: First beta implementation.

Installation:

  • From package managers:
  1. Search "QuickCore" on Delphinus package managers and click Install
  • From Github:
  1. Clone this Github repository or download zip file and extract it.
  2. Add QuickCore folder to your path libraries on Delphi IDE.
  3. Clone QuickLib Github repository https://github.com/exilon/QuickLib or download zip file and extract it.
  4. Add QuickLib folder to your path libraries on Delphi IDE.
  5. Clone QuickLogger Github repository https://github.com/exilon/QuickLogger or download zip file and extract it.
  6. Add QuickLogger folder to your path libraries on Delphi IDE.

Documentation:

QuickCore is a framework to easy build desktop/mobile/web apps.

DependencyInjection

Entire Framework is based on dependency injection priciples. A container holds all services needed by the application, allowing easy infrastructure changes with a minor enfort.

Services are automatically injected into server and configured from a single unit "startup". Every Core project needs a startup.pas with a class inheriting from TStartupBase (see examples on samples folder).

ServiceCollection:

It's a collection of services where we can register predefined or custom services and control its lifecycle (singleton, transient,..). ServiceCollection is the build-in container included in QuickCore and supports constructor injection by default.

services
   .AddLogging(TLoggerBuilder.GetBuilder(TLoggerOptionsFormat.ofYAML,False)
        .AddConsole(procedure(aOptions : TConsoleLoggerOptions)
            begin
              aOptions.LogLevel := LOG_DEBUG;
              aOptions.ShowEventColors := True;
              aOptions.ShowTimeStamp := True;
              aOptions.ShowEventType := False;
              aOptions.Enabled := True;
            end)
        .AddFile(procedure(aOptions : TFileLoggerOptions)
            begin
              aOptions.FileName := '.\WebApiServer.log';
              aOptions.MaxFileSizeInMB := 200;
              aOptions.Enabled := True;
            end)
        .Build
    )
  .AddDebugger
  .AddOptions(TOptionsFileFormat.ofYAML,True)
   //add entity database
  .Extension<TEntityServiceExtension>
    .AddDBContext<TShopContext>(TDBContextOptionsBuilder.GetBuilder.UseSQLite.ConnectionStringName('ShopContext').Options)
  //add Identity
  .Extension<TAuthenticationServiceExtension>()
    .AddIdentity<TUser,TRole>(procedure(aOptions : TIdentityOptions)
      begin
        aOptions.Password.RequiredLength := 6;
        aOptions.User.RequireUniqueEmail := True;
      end)
    .AddEntityStore<TShopContext>();
  //add Authentication
  services.Extension<TAuthenticationServiceExtension>()
    .AddAuthentication(procedure(aOptions : TAuthenticationOptions)
      begin

      end);
  //add ApiKey Authentication
  services.Extension<TApiKeyAuthenticationServiceExtension>
    .AddApiKey()
      .UseIdentityStore<TUser,TRole>('ApiKey');
  //add Authorization
  services.Extension<TAuthorizationServiceExtension>
    .AddAuthorization(procedure(aOptions : TAuthorizationOptions)
      begin
        aOptions.AddPolicy('ApiKeyValidation',TAuthorizationPolicyBuilder.GetBuilder
          .RequireAuthenticatedUser.Build
          //.RequireClaim(TClaimTypes.Role,'Admin').Build
        );
      end);

Basic Services

Logging:

QuickCore works with ILogger interface. We can use build-in Logging extension or define own implementation and inject it.

To use QuickLogger implementation (Needs QuickLogger library. See installation requirements). QuickLogger uses an ILogger builder to easy configuration. Default options can be passed as Options delegate function. When QuickLogger config file exists, no default options will be applied more:

services
   .AddLogging(TLoggerBuilder.GetBuilder(TLoggerOptionsFormat.ofYAML,False)
        .AddConsole(procedure(aOptions : TConsoleLoggerOptions)
            begin
              aOptions.LogLevel := LOG_DEBUG;
              aOptions.ShowEventColors := True;
              aOptions.ShowTimeStamp := True;
              aOptions.ShowEventType := False;
              aOptions.Enabled := True;
            end)
        .AddFile(procedure(aOptions : TFileLoggerOptions)
            begin
              aOptions.FileName := '.\WebApiServer.log';
              aOptions.MaxFileSizeInMB := 200;
              aOptions.Enabled := True;
            end)
        .Build
    );

...or add own logger implementation

services.AddLogging(MyLogger);

QuickCore logging config file is saved as QuickLogger.yml o json file. Using CORE_ENVIRONMENT environment variable we can define what file use for each implementation. If environment variable is defined, QuickCore will try to load/save "QuickCore.[CORE_ENVIRONMENT].yaml/json" file.

Options:

QuickCore works with Options pattern. Every TOptions object will be saved as a section in config file and can be injected into services or controllers constructors. Options service needs to added to ServiceCollection before we can add sections. We can define config filename and Json or Yaml format.

.AddOptions(TOptionsFileFormat.ofYAML,True)

Every config section needs to be added, and can be configured with default values.

services.Configure<TAppSettings>(procedure(aOptions : TAppSettings)
                           begin
                             aOptions.Smtp := 'mail.domain.com';
                             aOptions.Email := '[email protected]';
                           end)

and we can inject it later as simple as...

constructor TMyController.Create(aLogger : ILogger; aAppSettings : IOptions<TAppSettings>);
begin
    fOptions := aAppSettings.Value;
    fSMTPServer.Host := fOptions.Smtp;
end;

Into startup config you can use read options to do some optional actions:

  if services.GetConfiguration<TAppSettings>.UseCache then
  begin
    //do some stuff or define service implementation
  end
  else
  begin
    //do some stuff or define alternative service implementation
  end;

Using CORE_ENVIRONMENT environment variable we can define what file use for every implementation. If environment variable is defined, QuickCore will try to load/save "QuickCore.[CORE_ENVIRONMENT].yaml" file.

If not Options.Name is defined, class name will be used as section name in config file. Every Configured Option will be save and load to config file, but if we want, we can hide some options from been saved. Use Options.HideOptions := True (for internal options not configurable externally).

Debugger:

Debugger is a simple tracer-debugger (See QuickLib documentation). To connect debugger with a logging service only needs to add Debugger service in ServiceCollection (by default uses a console output):

services.AddDebugger;

Commandline parameters:

Working with commandline parameters will be easy using commandline extension. Define a class inherited from TParameters or TServiceParameters (if working with QuickAppServices) with your possible arguments:

uses
  Quick.Parameters;
type
  TArguments = class(TParameters)
  private
    fPort : Integer;
    fSilent : Boolean;
  published
    [ParamCommand(1)]
    [ParamHelp('Define listen port','port')]
    property Port : Integer read fPort write fPort;
    property Silent : Boolean read fSilent write fSilent;
  end;

And pass to de commandline extension:

services.AddCommandline<TArguments>;

When you call your exe with --help you get documentation. If you need to check for a switch or value, you can do like this:

if services.Commandline<TArguments>.Port = 0 then ...
if services.Commandline<TArguments>.Silent then ...

Add custom services:

Interfaces and Implementations can be added to ServiceCollection. AddSingleton and AddTransient allow define live cycle.

services.AddSingleton<IMyService,TMyService>;

or with delegated creation

services.AddTransient<IMyService,TMyService>(function : TMyService)
    begin
        Result := TMyService.Create(myparam);
        Result.Host := 'localhost';
    end);

or add an implementation

services.AddSingleton<TMyService>;

Extensions

Extensions are injectable services we can add to our app/server. Extensions are injected into ServiceCollection startup unit. ServiceCollection method Extensions works similar to .net extension methods, extendending ServiceCollection.

To add an extension, we need to add its unit to Startup unit uses clause (See QuickCore predefined extensions above).

uses
    Quick.Core.Extensions.AutoMapper;
...
begin
    services.Extension<TAutoMapperServiceExtension>
    .AddAutoMapper;
end;

MVC Server

With QuickCore we can create web applications with controllers and actions.

Create AppServer

Create an application server and define binding and security.

ApiServer := TMvcServer.Create('127.0.0.1',8080,False);
ApiServer.UseStartup<TStartup>;
ApiServer.Start;
```delphi
To configure services and middlewares startup must configured
```delphi
class procedure TStartup.Configure(app : TMVCServer);
begin
  app
  .AddControllers
  .AddController(THomeController)
  .DefaultRoute(THomeController,'Home/Index')
  .UseWebRoot('.\wwwroot')
  .UseRouting
  .UseMVC;
end;

AddController(ControllerClass): Allow add a controller to an web app server.

AddControllers: Add all controllers registered during its initialization unit with RegisterController(ControllerClass);

UseWebRoot(path): Define static files/data folder.

UseCustomErrorPages: Enable use of custom error pages. On a 403 error, server will search for a 403.html, 40x.html or 4xx.html files. If dinamic page specified, simple mustache patterns will be replaced with error info (StatusCode, StatusMsg, etc).

UseMustachePages: Simple mustache template engine to replace simple views.

Middlewares:

Middlewares are like layers of functionality and runs into a request pipeline. Every request pass for each middlwares (in creation order) or not, depending of middelware requeriments.

UseStaticFiles: To allow serve static content.

UseHsts: Http Strict Transport Security middleware to allow only https connections.

UseHttpsRedirection: Enables redirection middleware to redirect on header location found.

UseRouting: Enables Routing middleware to get matching route from request.

UseMVC: Enable MVC middleware to manage and redirect every request to its correspondent controller action or view.

UseMiddleware: To add custom middleware class to request pipeline.

Use(RequestDelegate): Execute an anonymous method as a middleware.

UseAuthentication: Tries to get authentication info from a request.

UseAuthorization: Allow/Disallow acces to resources based on authorization policies.

Controllers

Every controller inherites from THttpController and published methods becomes actions. With custom attributes we can define routing, authorization, etc of these methods. As all controllers are injected from dependency injection, we can define constructor with autoinjectable parameters and IOC will try to resolve on constructor creation.

constructor THomeController.Create(aLogger: ILogger);

Routing

Http routing is custom attributes based. We need to define routing for each controller and method/action.

[HttpGet('home/index')]
function THomeController.Index : IActionResult;

[HttpPost('home/GetAll')]
function THomeController.GetAll : IActionResult;

If routing defined on class, then it's global and doesn't need to be replicated on each method/action:

[Route('home/other')]
THomeController = class(THttpController)
published
    [HttpPost('GetAll')] // global + local = home/other/GetAll
    function THomeController.GetAll : IActionResult;

Attributes

  • [NonAction] Method not configured as an action method.
  • [ActionName] Defines name of action if different from method name.
  • [Route] Defines controller routing or action routing.
  • [HttpGet(route)] Defines a route with a GET method.
  • [HttpPost(route)] Defines a route with a POST method.
  • [HttpPut(route)] Defines a route with a PUT method.
  • [HttpDelete(route)] Defines a route with a DELETE method.
  • [HttpMethod(method)] Defines a custom method.
  • [AccepVerbs([verbs])] Defines all accepted verbs.
  • [Authorize] Limits acces to a controller or single method to only authenticated users.
  • [Authorize(role)] Limits access to a controller or single method to users with x role/s.
  • [AllowAnonymous] If global attribute defines a more restricted authorization, using this on a method allow access it without.
  • [OutputCache(TTL)] If ResponseCaching middleware defined, then response from this action will be saved and retrieved from cache while TTL interval not reached.

Handling parameters

Parameters are defined with attributes and automatically parsed and injected as method parameters.

[HttpGet('Add/{productname}/{price}')]
function Add(const ProductName : string; Price : Integer): IActionResult;

Parameters can be typed defined. Int: numeric only alpha: only letters. Float: only floating numbers.

[HttpGet('Add/{productname:alpha}/{price:float}')]
function Add(const ProductName : string; Price : Extended): IActionResult;

An ? define a parameter as optional

[HttpGet('Add/{productname:alpha}/{price:float?}')]
function Add(const ProductName : string; Price : Extended): IActionResult;

To get a parameter from the request body (with automatic deserialization)

[HttpPost('Add/User')]
function Add([FromBody] User : TUser): IActionResult;

Action Results

Action results are results of a controller. StatusCode(statuscode, statustext): Returns a status code and optional status text to client.

    Result := StatusCode(200,'ok');

Ok(statustext): Returns a 200 status code and optional statustext.

Accepted(statustext): Returns a 202 status code and optional status text.

BadRequest(statustext): Returns a 400 status code and optional status text.

NotFound(statustext): Returns a 404 status code and optional status text.

Forbid(statustext): Returns a 403 status code and optional status text.

Unauthorized(statustext): Returns a 401 status code and optional status text.

Redirect(url): Returns a temporal redirection to url.

RedirectPermament(url): Returns a permanent redirection to url.

Content(text): Returns a response text.

Json(object,onlypublishedproperties): Returns a serialized json object or list. If OnlyPublishedProperties enabled, only object published properties will be serialized.

    Result := Json(User);

View(viewname): Returns a view.

    Result := View('home');

Core Extensions

AutoMapper:

Automapper extension allows map a class type to another class type. To use Automapper we must add service to ServiceCollection in Statup unit:

services.Extension<TAutoMapperServiceExtension>
    .AddAutoMapper;

Then define profile maps with mapping relationship. If property names are identical, we should not have to manually provide a mapping:

constructor TMyProfile.Create;
begin
  //maps properties with same name in both classes
  CreateMap<TDBUser,TUser>();
end;

initialization
  TAutoMapper.RegisterProfile<TMyProfile>;

If some properties have diferent name or type, we must use custom mappings:

constructor TMyProfile.Create;
begin
  //maps properties with delegate function and rest maps formember
  CreateMap<TDBProduct,TProduct>(procedure(src : TDBProduct; tgt : TProduct)
    begin
      tgt.Id := src.uid;
      tgt.Age := src.Age;
    end)
    .ForMember('Money','Cash')
    .ForMember('Name','FullName')
    .IgnoreOtherMembers;
end;

initialization
  TAutoMapper.RegisterProfile<TMyProfile>;

ForMember(SourceProperty,TargetProperty): Maps a source property name to a target property name. IgnoreAllNonExisting: Ignore all non existing properties on target.

IgnoreOtherMembers: Only properties defined in custom mapping will be resolved.

ResolveUnmapped: Tries to resolve automatically any map without a profilemap defined.

AutoMapper service can be injected into a object/controller defining the abstraction in uses clauses.

uses
    Quick.Core.Mapping.Abstractions;
...
    TMyController.Create(aMapper : IMapper);

..and use it:

product := fMapper.Map(dbproduct).AsType<TProduct>;

..more documentation soon

Do you want to learn delphi or improve your skills? learndelphi.org

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].