Rui Vaz
Rui Vaz

Reputation: 41

Prolog receiving Json post

This is my first question in stackoverflow so, bear with me.

I'm tring to build a simple Prolog api that receives json posts and after processing them, sends another json post back. I found this code to receive the json:

handle(Request) :-
    http_read_json_dict(Request, DictIn),
    compute(DictIn, DictOut),
    reply_json(DictOut).

I assume that compute is a custom predicate, which for test purposes is test(D,D).

The problem is that when I try to test handle(Request) in swi-prolog I get either the error message ERROR: atom_codes/2: Arguments are not sufficiently instantiated or I get false.

I assume I just have to pass a json in the Request but it's not working. I also tried sending a post with Postman with a json file in the body (raw and application/json) but i get a timeout, which eh..yea... My question is what do I write in Request so that it instantiates it properly?

Thanks in advance and sorry if it's a bad/noobie question, but swi-prolog documentation is terrible and i can't find an answer anywhere.

Upvotes: 3

Views: 2042

Answers (2)

user9904704
user9904704

Reputation:

There are also a couple of JSON reader/writers around:

Thise modules take atoms and is implemented via DCG:
https://github.com/khueue/prolog-json/tree/master/src

This module is coded directively over ISO streams:
https://gist.github.com/jburse/63986bf525784d6d8cf99db132538d67#file-json_io-p

Both approaches don't require Prolog dicts and are suitable for a wide range of Prolog systems.

Upvotes: 0

gniourf_gniourf
gniourf_gniourf

Reputation: 46903

I'm not too sure you fully understand how Prolog and swi-prolog's web framework works.

Here's a step-by-step mini-tutorial to get you started:

  1. copy this in a file called myserver.pl:

    :- use_module(library(http/thread_httpd)).
    :- use_module(library(http/http_dispatch)).
    
    :- use_module(library(http/http_json)).
    
    :- http_handler(root(.),handle,[]).
    
    server(Port) :-
       http_server(http_dispatch,[port(Port)]).
    
    handle(Request) :-
       format(user_output,"I'm here~n",[]),
       http_read_json(Request, DictIn,[json_object(term)]),
       format(user_output,"Request is: ~p~n",[Request]),
       format(user_output,"DictIn is: ~p~n",[DictIn]),
       DictOut=DictIn,
       reply_json(DictOut).
    
  2. launch swi-prolog and in the main repl type:

    [myserver].
    

    to consult your file. You should have no errors. Then launch your server, say on port 8000:

    server(8000).
    

    You should have the following reply:

    % Started server at http://localhost:8000/
    
  3. open another terminal and post some json using curl:

    curl -H "Content-Type: application/json" -X POST -d '{"hello":"world"}' http://localhost:8000
    

    you should have the following reply:

    {"hello":"world"}
    

    and in the running prolog you should see these messages:

    I'm here
    Request is: [protocol(http),peer(ip(127,0,0,1)),pool(client('httpd@8000',user:http_dispatch,<stream>(0x7facc4026b20),<stream>(0x7facc4027040))),input(<stream>(0x7facc4026b20)),method(post),request_uri(/),path(/),http_version(1-1),user_agent('curl/7.35.0'),host(localhost),port(8000),accept([media(_G841/_G842,[],1.0,[])]),content_type('application/json'),content_length(17)]
    DictIn is: json([hello=world])
    

If you do any modifications to the file myserver.pl, you just need to type make. in prolog's repl.

I can't recommend enough Anne Ogborn's excellent tutorial. And by the way, swi-prolog's documentation is very good.

Upvotes: 2

Related Questions