Giter Club home page Giter Club logo

Comments (22)

silvioprog avatar silvioprog commented on July 19, 2024

A nice middleware idea: http://docs.slimframework.com/#Middleware-Overview

from brookframework.

uaply avatar uaply commented on July 19, 2024

Middleware is a good idea. It is used much in Django for example.

  TDownloadAction.Register('/download/:id');
  TDownloadAction.RegisterMiddleware(TMyMiddlewareClass);

Why we need to bind Middleware to Action? Usually it is bind to the whole Application. And all actions get a new functionality automatically. It can be used for example for authorization – usually all actions will need it. Middleware could be seen as modifying request/response objects. Sometimes Actions not even know about existence of Middleware, all new checks will be done transparent to Action. It is the point of Middleware – add a new functionality without touching Actions.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Why we need to bind Middleware to Action? Usually it is bind to the whole Application.

Hm... So, for middleware, we just add an OnRoute event. I'll add other events, like OnMatchPattern and OnMatchRegEx.

And in OnRoute you can implement for example an authorization.

And all actions get a new functionality automatically. It can be used for example for authorization – usually all actions will need it. Middleware could be seen as modifying request/response objects. Sometimes Actions not even know about existence of Middleware, all new checks will be done transparent to Action. It is the point of Middleware – add a new functionality without touching Actions.

Sorry, you're right. I confused the names hehe... The correct is:

  TDownloadAction.Register('/download/:id');
  TDownloadAction.RegisterConstraint(TMyConstraintClass);

I will implement it as soon as you fix the problem that I commented here. 👍

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

I started developing this new feature (constraints). I will commit it in coming days ...

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

@uaply , @leledumbo , I'm adding new events on the router. So, the english below is good?:

    { Is triggered when the router executes a action. }
    property OnExecuteAction;
    { Is triggered when the router match a pattern. }
    property OnMatchPattern;
    { Is triggered when the router is routing. }
    property OnRoute;

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Please, someone could document it for me?:

  { TODO: please help me in this documentation. }
  TBrookExecuteActionEvent = procedure(AAction: TBrookAction;
    ARequest: TRequest; AResponse: TResponse;
    ANames, AValues: TBrookArrayOfString) of object;

  { TODO: please help me in this documentation. }
  TBrookMatchPatternEvent = procedure(APattern, APathInfo: string;
    out ARedirect: Boolean; out ANames, AValues: TBrookArrayOfString) of object;

  { TODO: please help me in this documentation. }
  TBrookRouteEvent = procedure(ARequest: TRequest;
    AResponse: TResponse) of object;

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

And:

    { TODO: }
    property AfterExecuteAction: TBrookExecuteActionEvent
      read FAfterExecuteAction write FAfterExecuteAction;
    { TODO: }
    property AfterMatchPattern: TBrookMatchPatternEvent
      read FAfterMatchPattern write FAfterMatchPattern;
    { TODO: }
    property AfterRoute: TBrookRouteEvent read FAfterRoute
      write FAfterRoute;

    { TODO: }
    property BeforeExecuteAction: TBrookExecuteActionEvent
      read FBeforeExecuteAction write FBeforeExecuteAction;
    { TODO: }
    property BeforeMatchPattern: TBrookMatchPatternEvent
      read FBeforeMatchPattern write FBeforeMatchPattern;
    { TODO: }
    property BeforeRoute: TBrookRouteEvent read FBeforeRoute
      write FBeforeRoute;

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Oops, please discard documentation for ExecuteAction. It is a class method and will not have events.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

Is triggered when the router match a pattern

Is triggered when the router match es a pattern

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Thank you friend! 👍

Now, the full implementation is (please see the TODOs):

  { TODO: please help me in this documentation. }
  TBrookMatchPatternEvent = procedure(ASender: TObject;
    APattern, APathInfo: string; out ARedirect: Boolean;
    out ANames, AValues: TBrookArrayOfString) of object;

  { TODO: please help me in this documentation. }
  TBrookRouteEvent = procedure(ASender: TObject; ARequest: TRequest;
    AResponse: TResponse) of object;

...

  { Provides features for the route handling. }
  TBrookRouter = class(TBrookObject)
  ...
  public
  ...
    { TODO: please help me in this documentation. }
    property AfterMatchPattern: TBrookMatchPatternEvent
      read FAfterMatchPattern write FAfterMatchPattern;
    { TODO: please help me in this documentation. }
    property AfterRoute: TBrookRouteEvent read FAfterRoute
      write FAfterRoute;
    { TODO: please help me in this documentation. }
    property BeforeMatchPattern: TBrookMatchPatternEvent
      read FBeforeMatchPattern write FBeforeMatchPattern;
    { TODO: please help me in this documentation. }
    property BeforeRoute: TBrookRouteEvent read FBeforeRoute
      write FBeforeRoute;
  end;

...

function TBrookRouter.MatchPattern(APattern, APathInfo: string; out
  ARedirect: Boolean; out ANames, AValues: TBrookArrayOfString): Boolean;
...
begin
  if Assigned(FBeforeMatchPattern) then
    FBeforeMatchPattern(Self, APattern, APathInfo, ARedirect, ANames, AValues);
  ... implementation
  if Assigned(FAfterMatchPattern) then
    FAfterMatchPattern(Self, APattern, APathInfo, ARedirect, ANames, AValues);
end;

procedure TBrookRouter.Route(ARequest: TRequest; AResponse: TResponse);
...
begin
  if Assigned(FBeforeRoute) then
    FBeforeRoute(Self, ARequest, AResponse);
  ... implementation
  if Assigned(FAfterRoute) then
    FAfterRoute(Self, ARequest, AResponse);
  VAct := DoCreateAction(VActClass);
  try
    DoExecuteAction(VAct, ARequest, AResponse, VNames, VValues);
  finally
    DoFreeAction(VAct);
  end;
end;
...

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

I'm planning it:

{ turn it a non class method ... }procedure TBrookRouter.DoExecuteAction(AAction: TBrookAction;
  ARequest: TRequest; AResponse: TResponse; ANames, AValues: TBrookArrayOfString);
begin
  // before execute
  AAction.FillFields(ARequest);
  AAction.FillParams(ARequest);
  AAction.FillValues(ANames, AValues);
  // on execute
  AAction.DoRequest(ARequest, AResponse);
  // after execute
end;

... and borns the middleware in Brook router.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

The last implementation: http://pastebin.com/E5FjZ9iG

Can you help me in documentation?

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

After my last commit: http://pastebin.com/Kvwmr2Ww

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Now Brook router have middleware support (faebb2d).

Thank you! :)

from brookframework.

uaply avatar uaply commented on July 19, 2024

There is a new piece of code in brookrouter.pas:

procedure TBrookRouter.ExecuteAction(AAction: TBrookAction; ARequest: TRequest;
[...]
  if not VHandled then
  begin
    TLocalBrookAction(AAction).SetRequest(ARequest);
    TLocalBrookAction(AAction).SetResponse(AResponse);
    AAction.FillFields(ARequest);
    AAction.FillParams(ARequest);
    AAction.FillValues(ANames, AValues);
  end;
[...]

Why there is TLocalBrookAction(AAction) type-cast? Is it safe to cast class TBrookAction to it's descendant TLocalBrookAction? Maybe it works, but what is purpose of TLocalBrookAction?

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Hello friend,

Yes, it is ugly, but was the only way I found to avoid circular reference between units. :/

Can you help me in this design problem? It already works, but I think that we can improve the design.

from brookframework.

uaply avatar uaply commented on July 19, 2024

Oh, I see. TBrookRouter sets fields of foreign class. There is "friend class" in C++ for such cases.

It seems making methods SetRequest and SetResponse public solves this problem without additional class?

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Hm... So:

http://pastebin.com/9ptaZdKe

Fine?

from brookframework.

uaply avatar uaply commented on July 19, 2024

It looks good! And works with no forceful typecast.

Am I correct that you can't access ARequest from inside of BeforeExecuteAction event?
How would middleware know whether to handle request? And what it could do if it decide to handle it, AResponse is not accessible either.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Yes, you're already right. :)

Fixed. (414e520)

What do you think of us add two new parameters? E.g.:

  { Is a type to @code(*ExecuteAction) event. }
  TBrookExecuteActionEvent = procedure(ASender: TObject;
    AAction: TBrookAction; **ARequest: TRequest; AResponse: TResponse;**
    ARoute: TBrookRoute; var AHandled: Boolean) of object;

from brookframework.

uaply avatar uaply commented on July 19, 2024

Parameters are Okay as for me.

The other possibility is to set FRequest and FResponse of AAction before calling Event, but parameters are better (more apparent).

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Done. Thank you very much buddy! 👍

from brookframework.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.