1 /**
2  * Модуль общих абстракций контроллера web приложения
3  *
4  * Copyright: (c) 2015-2020, Milofon Project.
5  * License: Subject to the terms of the BSD 3-Clause License, as written in the included LICENSE.md file.
6  * Author: <m.galanin@milofon.pro> Maksim Galanin
7  * Date: 2020-04-30
8  */
9 
10 module dango.web.controller;
11 
12 public
13 {
14     import uniconf.core : UniConf;
15     import vibe.http.server : HTTPServerRequest, HTTPServerResponse,
16             HTTPServerRequestDelegate, HTTPMethod;
17     import dango.inject : DependencyContainer;
18 }
19 
20 private
21 {
22     import vibe.http.server;
23     import vibe.http.router : URLRouter;
24     alias isValidHandler = URLRouter.isValidHandler;
25     alias handlerDelegate = URLRouter.handlerDelegate;
26 
27     import dango.inject : ComponentFactory;
28     import dango.web.middleware : WebMiddleware;
29 }
30 
31 
32 /**
33  * Функция регистрации цепочки оработки запроса
34  */
35 alias RegisterChainCallback = void delegate(HTTPMethod, string, Chain) @safe;
36 
37 
38 /// Фабрика web контроллера
39 alias WebControllerFactory = ComponentFactory!(WebController, DependencyContainer, UniConf);
40 
41 
42 /**
43  * Интерфейс для контроллера
44  */
45 interface WebController
46 {
47     /**
48      * Регистрация цепочек маршрутов контроллера
49      * На каждый обработчик формируется вызов dg
50      * Params:
51      * dg = Функция регистрации цепочки
52      */
53     void registerChains(RegisterChainCallback dg) @safe;
54 }
55 
56 
57 /**
58  * Декоратор обработчика запросов добавляющий функционал цепочки вызовов
59  * На основе обработчика формируется цепочка обработки вызова
60  */
61 class Chain : HTTPServerRequestHandler
62 {
63     private HTTPServerRequestDelegate _head;
64 
65     /**
66      * Main contructor
67      */
68     this(Handler)(Handler handler) @safe
69         if (isValidHandler!Handler)
70     {
71         _head = handlerDelegate(handler);
72     }
73 
74     /**
75      * Прикреаляет Middleware для текущего обработчика
76      * Params:
77      * handler = Обработчик
78      */
79     void attachMiddleware(WebMiddleware middleware) @safe
80     {
81         _head = handlerMiddleware(middleware, _head);
82     }
83 
84     /**
85      * Обработка запроса
86      */
87     final void handleRequest(scope HTTPServerRequest req, scope HTTPServerResponse res) @safe
88     {
89         _head(req, res);
90     }
91 
92     /**
93      * Создание обработчика на основе WebMiddleware
94      */
95     private HTTPServerRequestDelegateS handlerMiddleware(Handler)(WebMiddleware middleware,
96             Handler next) if (isValidHandler!Handler)
97     {
98         return (scope HTTPServerRequest req, scope HTTPServerResponse res) @safe
99         {
100             middleware.handleRequest(req, res, handlerDelegate(next));
101         };
102     }
103 }
104