Reputation: 41
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
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
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:
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).
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/
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