Prolog HTTP Dispatch句柄封装

时间:2016-12-17 12:19:11

标签: http prolog swi-prolog

我正在使用HTTP服务器在Prolog中创建程序来发出请求......

我希望以一种可以重复使用它的方式封装代码,并将http内容放在一个模块中,我的"控制器"处理另一个模块中的请求等

我开始遇到http调度处理程序注册问题:

:- http_handler('/test', foobar, []).  

是否有可能有这样的事情:

register_handler(path, callback) :-
    http_handler(path, callback, []).  

我尝试使用它,但我得到一个错误,可能是由于"回调"参数。此外,回调谓词在不同的模块中定义,因此我使用了:

:-consult(api_controller).

[编辑]

server.pl

:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_parameters)).
:- use_module(library(http/http_json)).

:- use_module(api_controller).

:- http_handler('/test', foo, []).  

server(Port):-http_server(http_dispatch, [port(Port)]).

api_controller.pl

foo(_request) :-
    format('Content-type: text/plain~n~n'),
    format('Hello world!~n').

错误

http_dispatch:call_action/2: Undefined procedure: foo/1

1 个答案:

答案 0 :(得分:2)

http_handler/3指令,您可以将此类指令放在其他文件中,然后使用include/1加载它们。

此外,您可以通过安装通用处理程序对HTTP分派进行完全控制,如下所示:

:- http_handler(/, handle_request, [prefix]).

请注意prefix选项。

然后,您提供了一个合适的handle_request/1,例如:

handle_request(Request) :-
        debug(my_dispatch, "~q\n", [Request]),
        memberchk(path(Path0), Request),
        atom_concat(., Path0, Path1),
        http_safe_file(Path1, []),
        absolute_file_name(Path1, Path),
        (   reply_file(Path0, File) -> http_reply_file(File, [unsafe(true)], Request)
        ;   redirect(Path0, Other)  -> http_redirect(moved, Other, Request)
        ;   see_other(Path0, Other) -> http_redirect(see_other, Other, Request)
        ;   hidden_file(Path0)      -> http_404([], Request)
        ;   exists_file(Path)       -> http_reply_file(Path, [unsafe(true)], Request)
        ;   ...
        ).

在此示例中,以下谓词旨在由 you 提供,以根据您的确切用例定制服务器:

  • reply_file(Path, File):发送内容File以回复请求Path
  • redirect(Path0, Path):重定向到Path以回复Path0
  • see_other/2:意思留作练习。
  • hidden_file/1:意思留作练习。

这些规则可以在别处定义,您可以使用指令包含这些文件:

:- include(other_source).

您应该检查的相关指令是multifile/1

我留下了上面作为练习所需的精确图书馆。一个起点:

:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_server_files)).
:- use_module(library(http/http_files)).
:- use_module(library(http/http_header)).