# Using JSON with SWI-Prolog

**URL:** <https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828>\
**Category:** Split Topic\
**Created:** [August 26, 2020, 1:18pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828 "2020-08-26T13:18:13Z")\
**Posts on this page:** 11\
**Page:** 1

<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 26, 2020, 1:18pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/1 "2020-08-26T13:18:13Z")

</div>

This is a topic that was split off from [How to avoid escaping characters in Prolog strings](https://swi-prolog.discourse.group/t/how-to-avoid-escaping-characters-in-prolog-strings/2827)

* * *

> [@How to avoid escaping characters in Prolog strings (Discussion)](https://swi-prolog.discourse.group/t/how-to-avoid-escaping-characters-in-prolog-strings-discussion/3211/1):
>
> That said why would you need a hard coded JSON string in your code except when writing tests for a JSON parser?

The need is to create JSON for use with [Cytoscape.js](https://js.cytoscape.org/) graphs which uses JSON to define the nodes and edges of the graph. ([ref](https://js.cytoscape.org/#notation/elements-json)) As was done with creating nodes and edges for use with [GraphViz](https://graphviz.org/) using DCGs, the plan is to create Cytoscape.js graphs with DCGs. ([ref](https://swi-prolog.discourse.group/t/convert-facts-to-graphviz-dot-file-using-dcgs/2809)).

* * *

> **Personal Notes**
>
> [Supporting JSON](https://www.swi-prolog.org/pldoc/man?section=jsonsupport)  
> [library(http/json)](https://www.swi-prolog.org/pldoc/man?section=json): Reading and writing JSON serialization  
> [library(http/json\_convert)](https://www.swi-prolog.org/pldoc/man?section=jsonconvert): Convert between JSON terms and Prolog application terms  
> [library(http/http\_json)](https://www.swi-prolog.org/pldoc/man?section=httpjson): HTTP JSON Plugin module - If you are not using an HTTP server then instead look at [library(http/json)](https://www.swi-prolog.org/pldoc/man?section=json)
> 
> [library(http/js\_write)](https://www.swi-prolog.org/pldoc/man?section=jswrite): Utilities for including JavaScript
> 
> Anne’s site ([JSON](http://www.pathwayslms.com/swipltuts/html/index.html#_json))
> 
> [JSONLint](https://jsonlint.com/) - The JSON Validator
> 
> [library(quasi\_quotations)](https://www.swi-prolog.org/pldoc/man?section=quasiquotations): Define Quasi Quotation syntax  
> Why It’s Nice to be Quoted: Quasiquoting for Haskell ([pdf](https://www.cs.tufts.edu/comp/150FP/archive/geoff-mainland/quasiquoting.pdf))  
> Why It’s Nice to be Quoted: Quasiquoting for Prolog ([pdf](https://www.swi-prolog.org/download/publications/quasiquoting.pdf))  
> Implementing GraphQL as a Query Language for Deductive Databases in SWI–Prolog Using DCGs, Quasi Quotations, and Dicts ([pdf](https://arxiv.org/pdf/1701.00626.pdf))
> 
> Quasi-quotation ([Wikipedia](https://en.wikipedia.org/wiki/Quasi-quotation))  
> String interpolation ([Wikipedia](https://en.wikipedia.org/wiki/String_interpolation#JavaScript))
> 
> > Expansion of the string usually occurs at [run time](https://en.wikipedia.org/wiki/Run_time_(program_lifecycle_phase)).
> 
> Template processor ([Wikipedia](https://en.wikipedia.org/wiki/Template_processor))
> 
> > A template engine is ordinarily included as a part of a [web template system](https://en.wikipedia.org/wiki/Web_template_system) or [application framework](https://en.wikipedia.org/wiki/Application_framework), and may be used also as a [preprocessor](https://en.wikipedia.org/wiki/Preprocessor) or [filter](https://en.wikipedia.org/wiki/Filter_(software)).
> 
> Code examples using Quasi Quotations  
> [https://github.com/xpxaxsxi/qqospath/blob/branch1/qqospath.pl](https://github.com/xpxaxsxi/qqospath/blob/branch1/qqospath.pl)  
> [https://github.com/mndrix/uri\_qq/blob/master/prolog/uri\_qq.pl](https://github.com/mndrix/uri_qq/blob/master/prolog/uri_qq.pl)  
> [http://www.pathwayslms.com/swipltuts/html/index.html#\_inclusion](http://www.pathwayslms.com/swipltuts/html/index.html#_inclusion)  
> [https://github.com/NaohiroTamura/graphql/blob/622ddbb111a7583a0d9edfb5b33a06e68baacdfd/prolog/graphql.pl](https://github.com/NaohiroTamura/graphql/blob/622ddbb111a7583a0d9edfb5b33a06e68baacdfd/prolog/graphql.pl)  
> [https://github.com/TeamSPoon/logicmoo\_nlu/blob/a9924b3d14fd97bcd900e4a8cb4ceefd2d51f93e/prolog/marty\_white/adv\_quasiquote.pl](https://github.com/TeamSPoon/logicmoo_nlu/blob/a9924b3d14fd97bcd900e4a8cb4ceefd2d51f93e/prolog/marty_white/adv_quasiquote.pl)  
> [https://github.com/NaohiroTamura/openwhisk-runtime-prolog/blob/dc35da81020e722081c100ac14d4dcc924f8b340/samples/actions/graphql.pl](https://github.com/NaohiroTamura/openwhisk-runtime-prolog/blob/dc35da81020e722081c100ac14d4dcc924f8b340/samples/actions/graphql.pl)  
> [https://github.com/Hookscript/lang-prolog-swi/blob/390fa1b9e345f0e7112733953205fcf58e920769/packs/uri\_qq/prolog/uri\_qq.pl](https://github.com/Hookscript/lang-prolog-swi/blob/390fa1b9e345f0e7112733953205fcf58e920769/packs/uri_qq/prolog/uri_qq.pl)  
> [https://github.com/JanWielemaker/rserve\_client/blob/f5df41128164258a03158928d41eb81eeed0f24b/prolog/r/r\_call.pl](https://github.com/JanWielemaker/rserve_client/blob/f5df41128164258a03158928d41eb81eeed0f24b/prolog/r/r_call.pl)  
> [https://github.com/samer--/prolog/blob/574caf40a99afcd0e6fe2b5aeda2c725cd2fcd3b/pldb/prolog/pldb\_core.pl](https://github.com/samer--/prolog/blob/574caf40a99afcd0e6fe2b5aeda2c725cd2fcd3b/pldb/prolog/pldb_core.pl)

---

<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 26, 2020, 1:24pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/2 "2020-08-26T13:24:23Z")

</div>

> [@EricGT](#):
>
> which uses JSON to define the nodes and edges of the graph.

Why not create the equivalent SWI-Prolog dict objects and leave the transformation to JSON to json\_write\_dict/2? In the HTTP server context the skeleton is typically

```prolog
handler(Request) :-
    <get parameters>.
    <compute reply as a dict>,
    reply_json(Dict).

```

---

<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 26, 2020, 1:32pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/3 "2020-08-26T13:32:27Z")

</div>

> [@jan](#):
>
> Why not create the equivalent [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) dict objects and leave the transformation to JSON to [json\_write\_dict/2](https://www.swi-prolog.org/pldoc/doc_for?object=json_write_dict/2)? In the HTTP server context the skeleton is typically

Yes that is one option I plan to explore but find that doing some of the parts manually at first makes it easier to understand what is happening when the need to fix problems later happens.

I am more in the experimental stage than anything right now and have never really used JSON, SWI-Prolog dicts or Cytoscape.js to a level that I feel comfortable so this is like doing lots of homework problems to learn.

I didn’t even know json\_write\_dict/2 existed until just yesterday when trying to answer this other [question](https://swi-prolog.discourse.group/t/convert-atom-to-term-give-me-another-value-the-atom-value-is-a-variable/2820).

There is also the code by CapelliC ([GitHub - CapelliC/swish\_cytoscape\_js: SWISH graph rendering by means of cytoscape\_js](https://github.com/CapelliC/swish_cytoscape_js)) which I want to better understand.

---

<div class="post-metadata">

**Author:** ![kassepro](https://avatars.discourse-cdn.com/v4/letter/k/35a633/32.png) [@kassepro](https://swi-prolog.discourse.group/u/kassepro)\
**Post date:** [August 26, 2020, 2:49pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/4 "2020-08-26T14:49:44Z")

</div>

This subject is very important at the moment I handle json with prolog locally and I also use json\_object to create my json a and prolog\_to\_json objects as well as reply\_json with my local server it works but with aws I have to parse by hand json objects really it would be to be able to provide an answer to this problem

---

<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 26, 2020, 3:14pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/5 "2020-08-26T15:14:06Z")

</div>

> [@kassepro](#):
>
> with aws I have to parse by hand json objects really

Can you elaborate?

---

<div class="post-metadata">

**Author:** ![kassepro](https://avatars.discourse-cdn.com/v4/letter/k/35a633/32.png) [@kassepro](https://swi-prolog.discourse.group/u/kassepro)\
**Post date:** [August 26, 2020, 3:25pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/6 "2020-08-26T15:25:49Z")

</div>

To return the answer under aws with prolog I create the json object by hand with the concatenation using string\_concat and that not works in aws

---

<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 26, 2020, 3:48pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/7 "2020-08-26T15:48:16Z")

</div>

While my use case is not the exact same as yours, we do have touch points on

1. The format external to Prolog is JSON.
2. The internal format does not have to be JSON.

* * *

### SWI-Prolog internal representation

The internal representations that I need is currently facts in the Prolog database, see: [Convert facts to GraphViz dot file using DCGs](https://swi-prolog.discourse.group/t/convert-facts-to-graphviz-dot-file-using-dcgs/2809).

The SWI-Prolog [library(http/json)](https://www.swi-prolog.org/pldoc/man?section=json) does this with the internal representation being a dictionary and this is a reliable conversion. So if you are open to the format used with SWI-Prolog then using a [dictionary](https://www.swi-prolog.org/pldoc/man?section=bidicts), these predicates are handy.

AFAIK CapelliC uses `Unweighted Graphs`, see: [library(ugraphs)](https://www.swi-prolog.org/pldoc/man?section=ugraphs)

* * *

### Conversion

[library(http/json)](https://www.swi-prolog.org/pldoc/man?section=json) comes with predicates that convert to and from SWI-Prolog dictionaries.

I am using DCGs.

AFAIK CapelliC uses Quasi Quotation, see [library(quasi\_quotations)](https://www.swi-prolog.org/pldoc/man?section=quasiquotations)

Using a functional approach with [library(yall)](https://www.swi-prolog.org/pldoc/man?section=yall) is also a possibility but not one I plan to explore.

* * *

While I do like the reliability and ease of using [library(http/json)](https://www.swi-prolog.org/pldoc/man?section=json), for my specific use case that means I have to deal with dictionaries along the way. Since most of what I plan to generate will be [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code) the DCG still seems reasonable.

---

<div class="post-metadata">

**Author:** ![kassepro](https://avatars.discourse-cdn.com/v4/letter/k/35a633/32.png) [@kassepro](https://swi-prolog.discourse.group/u/kassepro)\
**Post date:** [August 26, 2020, 9:47pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/9 "2020-08-26T21:47:38Z")

</div>

![awserror](https://global.discourse-cdn.com/free1/uploads/swiprolog/original/2X/f/ff1732e7e7edcd2f82a84ac756c9e1d06feda6b4.png)

In local that works fine i have the result on aws a have this error

---

<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 26, 2020, 10:04pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/10 "2020-08-26T22:04:17Z")

</div>

When sending JSON to a Javascript from end using json\_write\_dict/3, I find these options useful: `[width(0),true(#(true)),false(#(false)),null(#(null))]`.

For reading with json\_read\_dict/3, I find these options useful:  
`[value_string_as(atom), end_of_file(@(end)), default_tag(json), true(#(true)),false(#(false)),null(#(null))]`.

(The `default_tag` is a small thing, but it gives me more peace of mind when using unification to compare two JSON-created dicts).

---

<div class="post-metadata">

**Author:** ![kassepro](https://avatars.discourse-cdn.com/v4/letter/k/35a633/32.png) [@kassepro](https://swi-prolog.discourse.group/u/kassepro)\
**Post date:** [August 26, 2020, 10:10pm UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/11 "2020-08-26T22:10:51Z")

</div>

In this case I use `reply_json` to send json response i create the json object with `json_object` in my computer i don’t have error when test it in aws i have an error.

My goal is create a lambda function in aws with prolog and the response have to respect this format :`{ "isBase64Encoded":`true|false`, "statusCode":`httpStatusCode`, "headers": { "`headerName`": "`headerValue`", ... }, "multiValueHeaders": { "`headerName`": ["`headerValue`", "`headerValue2`", ...], ... }, "body": "`…` " }` this the spec of aws in local i have the expected response

 ![correnResponseLocal](https://global.discourse-cdn.com/free1/uploads/swiprolog/original/2X/8/893dc83975e65a09086e62f213b6fb7f9bb1f9e1.png)

---

<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 27, 2020, 6:48am UTC](https://swi-prolog.discourse.group/t/using-json-with-swi-prolog/2828/12 "2020-08-27T06:48:33Z")

</div>

> [@kassepro](#):
>
> In local that works fine i have the result on aws a have this error

Suggest there is a bad call to format/3 in your code somewhere. Often you get more info if you load library(http/http\_error) in addition. That should add a backtrace to the output.

For interactive debugging, run the server with access to the toplevel and graphics (depends on platform how) and run

```
?- tspy(NameOfHandler).

```

That should open the debugger if you make the HTTP request.
