Why does including the library http_json change the behavior of my existing code?


#1

I’m using: SWI-Prolog version 8.0.1

This is a follow-up to an earlier question. I’m trying to update my old clunky PL server which was receiving and sending raw strings (and parsing them on the client side) to use JSON instead. The code below works. But if I uncomment the use_module(library(http/http_json)) directive, and make no changes to the main body of the code, it will fail, with:

% [Thread httpd@5000_4] POST /dataexchange: [500] Stream (0x7fe688018280):1:8 Syntax error: json(illegal_json)

My code looks like this:

:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_error)).
% :- use_module(library(http/http_json)).
:- use_module(library(http/html_write)).

:- use_module(library(http/http_client)).
:- http_handler('/', web_form, []).

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

web_form(_Request) :-
	reply_html_page(
	    title('POST demo'),
	    [
	       form([action='/', method='POST'], 
                [h1('Prolog Server')]
               )
        ]
    ).

:- http_handler('/dataexchange', dataexchange_handler, [time_limit(infinite)]).

dataexchange_handler(Request) :-
	debug_auto( ">>>RECEIVED request..."),
    convert_input_to_term( Request, Term ),
    debug_auto( "+++PROCESSING request"),
    general_predicate( Term, OutTerm ),
    debug_auto( "<<<REPLY"),
    reply_as_string( OutTerm ).

convert_input_to_term( Request, Term ) :-
    member(method(post), Request), !,
    http_read_data(Request, DataString, []),
    term_string( Term, DataString ).

general_predicate( InTerm, OutTerm ) :-
    call_findall_free_vars( InTerm, OutTerm ).
    
reply_as_string( Term ) :-
    term_string( Term, OutString ),
    format('Content-type: text/html~n~n', []),
    portray_clause(OutString).

Why does the mere inclusion of the http_jason module cause failure? Does it have side-effects such as effectively hiding other functions?


#2

This is a “plugin module” (see the docs). Yes, just including it changes the behaviour. You shouldn’t need to convert between strings and terms at all, you read json requests and write json responses. It is documented and explained in the docs: http://www.swi-prolog.org/pldoc/man?section=httpjson

(I did not read your code to figure out what exactly causes the error. Can you provide a test case?)


#3

Yes, I had wanted to have an intermediate developmental phase of testing where I was sending strings to the server (the old system) but returning JSON (the new system) rather than having to change everything at once, and then altering the send phase subsequently.


#4

I guess during the transition you might want to use library(http/json) instead? Not sure, I used them both at some point but I have forgotten exactly what use case each covered. I am sure other would be able to help you with more specific advice.


#5

Maybe this will help:
http://www.swi-prolog.org/pldoc/doc_for?object=atom_json_dict/3