# Interfacing with Angular

**URL:** <https://swi-prolog.discourse.group/t/interfacing-with-angular/2722>\
**Category:** Help!\
**Created:** [July 30, 2020, 12:19pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722 "2020-07-30T12:19:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [July 30, 2020, 12:19pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/1 "2020-07-30T12:19:02Z")

</div>

Hello,  
I’m using: SWI-Prolog version 6.2.2

I would like to interrogate my Prolog program from another language (Angular preferably).  
Is their a way to do so ?

Thank you !

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 30, 2020, 12:25pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/2 "2020-07-30T12:25:40Z")

</div>

> [@ILogre](#):
>
> I would like to interrogate my Prolog program from another language (Angular preferably).  
> Is their a way to do so ?

This is an advanced topic.  
See: [Foreign Language Interface](https://www.swi-prolog.org/pldoc/man?section=foreign)

* * *

> [@ILogre](#):
>
> [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) version 6.2.2

You should upgrade to the latest version. Upgrading is not hard.  
See:  
[Install SWI-Prolog development version on Ubuntu using PPA](https://swi-prolog.discourse.group/t/install-swi-prolog-development-version-on-ubuntu-using-ppa/2402)  
[Install SWI-Prolog development version on Windows](https://swi-prolog.discourse.group/t/install-swi-prolog-development-version-on-windows-10/1131)  
If you need Mac, then I can not help.

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [July 30, 2020, 12:38pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/3 "2020-07-30T12:38:39Z")

</div>

> [@EricGT](#):
>
> You should upgrade to the latest version. Upgrading is not hard.  
> See:  
> [Install SWI-Prolog development version on Ubuntu using PPA](https://swi-prolog.discourse.group/t/install-swi-prolog-development-version-on-ubuntu-using-ppa/2402)  
> [Install SWI-Prolog development version on Windows](https://swi-prolog.discourse.group/t/install-swi-prolog-development-version-on-windows-10/1131)

Actually I’m avoiding the development version on purpose, but I got the last stable one so I’m on 8.2.1 now.

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [July 30, 2020, 12:40pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/4 "2020-07-30T12:40:29Z")

</div>

> [@EricGT](#):
>
> This is an advanced topic.  
> See: [Foreign Language Interface](https://www.swi-prolog.org/pldoc/man?section=foreign)

Thank you. I was looking for a simple way, for example a swi-prolog web service.  
It seems to be a bit complicated comparatively to what we would gain to do it.  
Thanks !

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 30, 2020, 12:48pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/5 "2020-07-30T12:48:03Z")

</div>

> [@ILogre](#):
>
> for example a [swi-prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) web service.

Glad you added that quip.

This might suit your fancy.  
See: [Pengines: Web Logic Programming Made Easy](https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/pengines.html%27))

The author @torbjorn.lager hangs out here. He can tell you if this would fit your requirements.

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [July 30, 2020, 12:54pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/6 "2020-07-30T12:54:19Z")

</div>

Thanks ! That seems to be very interesting, I’ll take a look and contact Torbjörn Lager if it seems to fit our need.

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [July 30, 2020, 11:03pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/8 "2020-07-30T23:03:17Z")

</div>

@ILogre, I would definitely use the development version or at least the latest stable. 6.2.2 is way too ancient.

The easiest solution is to use pengines.js, second easiest would be direct HTTP JSON API with CORS (see the http\_server module). We don’t seem to have a good minimal “hello world”-type of example tho.

pengines.js is also available on NPM.

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [July 31, 2020, 6:25am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/9 "2020-07-31T06:25:19Z")

</div>

> [@EricGT](#):
>
> Something of interest: [Package “transpiler”](https://www.swi-prolog.org/pack/list?p=transpiler)

Interesting approach, but indeed I’m not sure it’s recommended in our case.  
Translating the Prolog program into Angular would be one thing (although it seems it’s not offered yet), but it would probably impact performances in a significant way.  
Thank you for the suggestion 😉

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [July 31, 2020, 6:33am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/10 "2020-07-31T06:33:51Z")

</div>

> [@rla](#):
>
> @ILogre, I would definitely use the development version or at least the latest stable. 6.2.2 is way too ancient.

I upgraded to 8.2.1 as said earlier 😉

> [@rla](#):
>
> second easiest would be direct HTTP JSON API with CORS (see the http\_server module)

I can’t find a “http\_module” on the CORS reference page ([Cross-Origin Resource Sharing (CORS) - HTTP | MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)).  
Is the http\_module a way to define a web server encompassing my Prolog program ?

Thank you for your suggestions, I’ll be sure to try Pengines.js first

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 31, 2020, 8:02am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/11 "2020-07-31T08:02:52Z")

</div>

There is a tutorial on web programming by Anne Ogborn at [http://www.pathwayslms.com/swipltuts/html/index.html](http://www.pathwayslms.com/swipltuts/html/index.html). Might not handle all of this, but it should give a starting point.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [July 31, 2020, 7:16pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/12 "2020-07-31T19:16:06Z")

</div>

The tutorial is slightly out of date … I was going to update it but haven’t got around to it.  
One item: [https://www.swi-prolog.org/pldoc/doc/\_SWI\_/library/http/index.html](https://www.swi-prolog.org/pldoc/doc/%5C_SWI%5C_/library/http/index.html)

> For simplicity, you can use `library(http/http_server)`, which combines the typical HTTP libraries that most servers need.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [July 31, 2020, 7:19pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/13 "2020-07-31T19:19:00Z")

</div>

There’s also [http://tau-prolog.org/](http://tau-prolog.org/) (Prolog interpreter in JavaScript).

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [August 3, 2020, 6:48am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/14 "2020-08-03T06:48:09Z")

</div>

> [@peter.ludemann](#):
>
> One item: [https://www.swi-prolog.org/pldoc/doc/](https://www.swi-prolog.org/pldoc/doc/) _SWI_ /library/http/index.html

I’m sorry, the link seems to be broken.  
I am really interest by a “template” or an example of a Prolog http server.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 3, 2020, 7:05am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/15 "2020-08-03T07:05:14Z")

</div>

[https://www.swi-prolog.org/pldoc/man?section=httpserver](https://www.swi-prolog.org/pldoc/man?section=httpserver)

> Most server implementation simply load the `library(http/http_server)` library, which loads the above modules and reexports all predicates except for those used for internal communication and older deprecated predicates. Specific use cases may load a subset of the individual libraries and may decide to replace one or more of them.

And skeleton code is also given.

There’s similar text at `https://www.swi-prolog.org/pldoc/doc/_SWI_/library/http/index.html` (which Discourse seems to have messed up, so I’ve quoted it here).

---

<div class="post-metadata">

**Author:** ![ILogre](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@ILogre](https://swi-prolog.discourse.group/u/ILogre)\
**Post date:** [August 3, 2020, 2:26pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/17 "2020-08-03T14:26:12Z")

</div>

Thank you all for your answers !

I will be sure to check [Pengines](https://www.swi-prolog.org/pldoc/doc_for?object=section(%27packages/pengines.html%27)), [CORES](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) and [HTTP\_Server](https://www.swi-prolog.org/pldoc/man?section=httpserver).  
If you have some qualitative feedback about the relative difficulties of these solutions, I’d be curious to know !

To provide some context, our problematic is quite simple :  
We are working on a class of problems usually tackled by a specific engine type.  
In our project, we are wondering is our elements could be seen as a sub-type of the classical problem.  
We would like to isolate a part of the classical engine behavior to develop it in Prolog, and then expose this behavior as a web service to be interrogated from external websites.  
So our requirements in terms of web server are quite low :

- expose a handful of functionalities (/services)
- wrap up the Prolog server with Docker to be deployed on a server.

It won’t be an intensive use, we won’t need persistence, nor to maintain sessions.  
So if you experienced with one or several of these solutions, do not hesitate to share your feedback !

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 3, 2020, 2:39pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/18 "2020-08-03T14:39:09Z")

</div>

With Pengines you might find the work of @sam.neaves of interest.

See: [Explorations in Logic Programming for Bioinformatics](https://www.swi-prolog.org/news/2a1c2196-db69-11e8-95a8-00163e986a2a)

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 4, 2020, 7:38am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/19 "2020-08-04T07:38:29Z")

</div>

> [@ILogre](#):
>
> So our requirements in terms of web server are quite low :
> 
> - expose a handful of functionalities (/services)
> - wrap up the Prolog server with Docker to be deployed on a server.

If the web API is fairly simple and stable I’d simply go for the core SWI-Prolog web libraries. You can use the [openapi](https://www.swi-prolog.org/pack/list?p=openapi) package to define the API using the OpenAPI 3 specs and generate the server skeleton. That can be worthwhile if the API is large and complex and may be changed frequently. Note that this package is rather experimental. It certainly has bugs dealing with corner cases of the OpenAPI spec.

Pengines are notably interested if you want to upload _programs_ to the server or you want to maintain/develop the programs you want to maintain using SWISH. Using SWISH you can develop and debug a program using the SWISH web interface, save it and use a Pengines client to run the saved program with given parameters. Pengines are less attractive if short response times are critical: you should add a couple of milliseconds the server needs to create a pengine and load the code into it.

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [August 13, 2020, 8:47pm UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/21 "2020-08-13T20:47:13Z")

</div>

I’ve been teaching myself WebSocket, and I’d say these days it’s the best way to glue just about any languages together.

For SWI Prolog, setting up a WebSocket server is nearly identical to an http server. The only additions are importing [library(http/websocket)](https://www.swi-prolog.org/pldoc/man?section=websocket) and modifying the second argument of [**http\_handler** (+Path, :Closure, +Options)](https://www.swi-prolog.org/pldoc/man?predicate=http_handler/3) to be inside [**http\_upgrade\_to\_websocket** (:Goal, +Options, +Request)](https://www.swi-prolog.org/pldoc/man?predicate=http_upgrade_to_websocket/3).

A simple ping-pong example (the “Hello World” of concurrent programming) looks like this on the SWI Prolog side:

```prolog
:- use_module(library(http/websocket)).
:- use_module(library(http/http_server)).
:- use_module(library(http/http_unix_daemon)).

:- initialization http_daemon.

:- http_handler(root(ws), http_upgrade_to_websocket(loop, []), [spawn([])]).

loop(Request) :-
  ws_receive(Request, Message, [format(json)]),
  ( Message.data.request == "close"
  -> ws_send(Request, close(1000, "normal"))
  ; request(Message.data.request, Message.data, Reply),
     ws_send(Request, json(Reply)),
     loop(Request)
  ).

request("ping", _Dict, json{reply: pong}).

```

and would be started on a Linux machine like

```bash
swipl server.pl --port=6455 --pidfile=http.pid

```

where I picked the port number in honour of WebSocket’s [RFC](https://tools.ietf.org/html/rfc6455) number.

_Edit to the above code: Following a tip from @jan in the comments below, I added [library(http/http\_server)](https://github.com/SWI-Prolog/packages-http/blob/master/http_server.pl) to the import list. It imports [library(http/http\_dyn\_workers)](https://github.com/SWI-Prolog/packages-http/blob/master/http_dyn_workers.pl) which is a better way of setting the number of threads than the --workers=4 in the shell command I originally used._

I’ve never used Angular, but assume the plain vanilla JavaScript code below would work:

```javascript
const prologServer = new WebSocket("ws://localhost:6455/ws");

prologServer.addEventListener("open", function(event) {
  prologServer.send(JSON.stringify({"request": "ping"}));
});

prologServer.addEventListener("message", function(event) {
  document.querySelector("#message").innerText = JSON.parse(event.data).reply;
});

prologServer.addEventListener("close", function(event) {
  prologServer.close();
});

window.addEventListener("unload", (event) => {
  prologServer.send(JSON.stringify({"request": "close"}));
});

```

I basically got into WebSocket by experimenting with getting Erlang and SWI Prolog to interface which I put examples of on [github](https://github.com/roblaing/erlang-webapp-howto/tree/master/unit7) showing using SWI Prolog as a server and Erlang as a client, and vice versa.

This style of programming, sending messages in JSON which SWI Prolog handily converts into a dictionary for easy reference (though one gotcha is the value is a string which needs to be translated into something manipulable) and then back, is very Erlangish. Known as the [actor model](https://en.wikipedia.org/wiki/Actor_model), it took me a bit of getting used to, but I’ve become a fan.

Though very easy when the URL is ws://localhost:portnumber, getting it to work on a public server where browsers insist on wss://samedomainname.com:portnumber is something I’m currently bashing my head against, learning far more about nginx configuration files than I ever wanted to.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 14, 2020, 7:21am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/22 "2020-08-14T07:21:09Z")

</div>

Thanks for sharing.

> [@joeblog](#):
>
> ` --workers=4`

This is a bit old. New code better use `library(http/http_dyn_workers)` or load all server basics using `library(http/http_server)`.

> [@joeblog](#):
>
> Though very easy when the URL is ws://localhost:portnumber, getting it to work on a public server where browsers insist on wss://samedomainname.com:portnumber is something I’m currently bashing my head against, learning far more about nginx configuration files than I ever wanted to.

On public ports some browsers insist on https (wss). If you use nginx as proxy you need something like below. This rule is from SWISH. The first two lines (resolver and proxy\_pass) are there to find the lxc container in which SWISH runs and probably needs adapting.

```prolog
        location /chat {
                resolver 10.0.3.1;
                proxy_pass http://$container$request_uri;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header X-Real-IP $remote_addr;
                proxy_read_timeout 86400;
        }

```

---

<div class="post-metadata">

**Author:** ![drspro](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/drspro/32/3509_2.png) [@drspro](https://swi-prolog.discourse.group/u/drspro)\
**Post date:** [August 14, 2020, 7:41am UTC](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722/23 "2020-08-14T07:41:18Z")

</div>

simpelst is to set up de swi- http server, then test that you can output data on http requests, then let the output be in JSON for example, then in Angular you can make ajax http calls, receive the data and let it parse and use the data

[Next page](https://swi-prolog.discourse.group/t/interfacing-with-angular/2722.md?page=2)
