REST server on Prolog, what does it look like?

As a small digression for the uninitiated in logical programming

in this text a magic session will be held with the exposure given approach

to create a REST server and its parameters are measured.



What's the catch? And everything is simple - we will do it on the Prolog (in the implementation of SWI-prolog) ...



So what you need. First, download (if not already) and install the actual swi-prolog

from his website www.swi-prolog.org . It is easier to create a small file of type rest.pl with the initial contents of the type

server.
continue to download it and edit it using the prolog system itself, like this

(examples are given for the linux console, but not much different from windows):



$echo "." > rest.pl $swipl ... ?- [rest]. true. ?- edit().
      
      





After that, an emacs-like editor will start and you can type everything in it.



So, in the beginning, we’ll indicate that we will use libraries and write what it means

server launch - in the prologue characters: - can be read as "this is":



 :- use_module(library(http/http_server)). :- use_module(library(http/http_json)). :- http_handler(/,(M), [method(M),methods([get,post]),time_limit(10000)]).  :- http_server(http_dispatch, [port(8080)]).
      
      





As you can see, we plan that the service will respond to the get and post methods.



Model problem



Now actually what we will do. Upon request, we will respond with a page with a number input field, when entering it, we will request the post method and calculate this Fibonacci number.



I.e:



 (get,_) :- (X),(X). (post,) :- http_parameters(,[val(,[integer])]), ().
      
      





OK it's all over Now! We already actually wrote our server ... The prolog is a declarative language - so we declared the processing options. By the way, any language can be used - I decided to write in places in Russian.



But hey, what is he doing? After all, the “form”, “answer” and “shorten” are our predicates and they are not defined yet. Let's fix it:



 ():- format('Content-type: text/html~n~n <html><body>  <br/> ~w </body></html>~n', []). ('<form method="POST"><input name="val"/></form>').
      
      





Well, here are two options for calculating - let us have only positive Fibonacci numbers:



 ():-  > 0, (0,1,1,,),(X), format(atom(),'~w    ~w<br/>~w',[,,X]), (). ():- (X), format(atom(),'  ~w  0<br/>~w',[,X]), ().
      
      





Well, it remains to determine actually what is the Fibonacci number:



 (_F, F1, N, N, F1) :- !. (F0, F1, I, N, F) :- F2 is F0+F1, I2 is I + 1, !,(F1, F2, I2, N, F).
      
      





This definition, of course, not on Feng Shui is not quite familiar, but is considered almost faster than if we wrote in C ...



So will this work? We check:



  ?- . % Started server at http://localhost:8080/ true.
      
      





So, the server seems to have started. By the way, it is multithreaded! To check you need to open the address

127.0.0.1 : 8080 / and enter some number - for example, 1000:

Fibonacci numbers calculation

1000 Fibonacci number equals

4346655768693745643568852767504062580

2564660517371780402481729089536555417

9490518904038798400792551692959225930

8032263477520968962323987332247116164

2996440906533187938298969649928516003

704476137795166849228875

Well, it works!



A small study of server performance - let's check the GET method (POST obviously strongly depends on a given number, so a 10,000,000 number is considered, of course, but a few seconds ...)



  $ ab -k -c 4 -n 4000 http://127.0.0.1:8080/ ... Concurrency Level: 4 Time taken for tests: 0.283 seconds Complete requests: 4000 Failed requests: 0 Keep-Alive requests: 4000 Total transferred: 1108000 bytes HTML transferred: 544000 bytes Requests per second: 14140.57 [#/sec] (mean) Time per request: 0.283 [ms] (mean) Time per request: 0.071 [ms] (mean, across all concurrent requests) Transfer rate: 3825.14 [Kbytes/sec] received ...
      
      





What 14140 requests per second with 10 threads - this is very good for a regular computer!



And yes, the prologue has such an opportunity - a logical look. So if you change something in the code, then you just need to type in the console



  ?- make.
      
      





And all your changes will work in new requests - nothing needs to be overloaded, stopped, etc.



I hope you were interested to see how to create a rest-server with such a simple example. Of course, you can describe the rest interface statically, as was done in the example, you can enter all sorts of variables, use part of the URL path as variables - well, in general, everything is as usual.



You can do this dynamically, change the logic of the program by creating, deleting and modifying predicates - a sort of self-modifying server whose work depends on history. You can connect databases. In general, everything is as usual, just working is simple and pleasant.



All Articles