http_json.pl -- HTTP JSON Plugin module
Most code doesn't need to use this directly; instead use library(http/http_server), which combines this library with the typical HTTP libraries that most servers need.
This module adds hooks to several parts of the HTTP libraries, making them JSON-aware. Notably:
- Make http_read_data/3 convert
application/json
andapplication/jsonrequest
content to a JSON term. - Cause http_open/3 to accept
post(json(Term))
to issue a POST request with JSON content. - Provide HTTP server and client utility predicates for reading and replying JSON:
- Reply to exceptions in the server using an JSON document rather
then HTML if the
Accept
header prefers application/json over text/html.
Typically JSON is used by Prolog HTTP servers. This module supports two JSON representations: the classical representation and the new representation supported by the SWI-Prolog version 7 extended data types. Below is a skeleton for handling a JSON request, answering in JSON using the classical interface.
handle(Request) :- http_read_json(Request, JSONIn), json_to_prolog(JSONIn, PrologIn), <compute>(PrologIn, PrologOut), % application body prolog_to_json(PrologOut, JSONOut), reply_json(JSONOut).
When using dicts, the conversion step is generally not needed and the code becomes:
handle(Request) :- http_read_json_dict(Request, DictIn), <compute>(DictIn, DictOut), reply_json(DictOut).
This module also integrates JSON support into the http client provided by http_client.pl. Posting a JSON query and processing the JSON reply (or any other reply understood by http_read_data/3) is as simple as below, where Term is a JSON term as described in json.pl and reply is of the same format if the server replies with JSON.
..., http_post(URL, json(Term), Reply, [])
- http_client:http_convert_data(+In, +Fields, -Data, +Options)[multifile]
- Hook implementation that supports reading JSON documents. It
processes the following option:
- json_object(+As)
- Where As is one of
term
ordict
. If the value isdict
, json_read_dict/3 is used.
- is_json_content_type(+ContentType) is semidet
- True if ContentType is a header value (either parsed or as atom/string) that denotes a JSON value.
- json_type(?MediaType) is semidet[multifile]
- True if MediaType is a JSON media type. http_json:json_type/1 is a multifile predicate and may be extended to facilitate non-conforming clients.
- http:post_data_hook(+Data, +Out:stream, +HdrExtra) is semidet[multifile]
- Hook implementation that allows http_post_data/3 posting JSON
objects using one of the forms below.
http_post(URL, json(Term), Reply, Options) http_post(URL, json(Term, Options), Reply, Options)
If Options are passed, these are handed to json_write/3. In addition, this option is processed:
- json_object(As)
- If As is
dict
, json_write_dict/3 is used to write the output. This is default ifjson(Dict)
is passed.
- http_read_json(+Request, -JSON) is det
- http_read_json(+Request, -JSON, +Options) is det
- Extract JSON data posted to this HTTP request. Options are
passed to json_read/3. In addition, this option is processed:
- json_object(+As)
- One of
term
(default) to generate a classical Prolog term ordict
to exploit the SWI-Prolog version 7 data type extensions. See json_read_dict/3.
- http_read_json_dict(+Request, -Dict) is det
- http_read_json_dict(+Request, -Dict, +Options) is det
- Similar to http_read_json/2,3, but by default uses the version 7 extended datatypes.
- reply_json(+JSONTerm) is det
- reply_json(+JSONTerm, +Options) is det
- Formulate a JSON HTTP reply. See json_write/2 for details.
The processed options are listed below. Remaining options are
forwarded to json_write/3.
- content_type(+Type)
- The default
Content-type
isapplication/json; charset=UTF8
.charset=UTF8
should not be required because JSON is defined to be UTF-8 encoded, but some clients insist on it. - status(+Code)
- The default status is 200. REST API functions may use other values from the 2XX range, such as 201 (created).
- json_object(+As)
- One of
term
(classical json representation) ordict
to use the new dict representation. If omitted and Term is a dict,dict
is assumed. SWI-Prolog Version 7.
- reply_json_dict(+JSONTerm) is det
- reply_json_dict(+JSONTerm, +Options) is det
- As reply_json/1 and reply_json/2, but assumes the new dict based data representation. Note that this is the default if the outer object is a dict. This predicate is needed to serialize a list of objects correctly and provides consistency with http_read_json_dict/2 and friends.
Re-exported predicates
The following predicates are exported from this file while their implementation is defined in imported modules or non-module files loaded by this module.
- http_read_json(+Request, -JSON) is det
- http_read_json(+Request, -JSON, +Options) is det
- Extract JSON data posted to this HTTP request. Options are
passed to json_read/3. In addition, this option is processed:
- json_object(+As)
- One of
term
(default) to generate a classical Prolog term ordict
to exploit the SWI-Prolog version 7 data type extensions. See json_read_dict/3.
- http_read_json_dict(+Request, -Dict) is det
- http_read_json_dict(+Request, -Dict, +Options) is det
- Similar to http_read_json/2,3, but by default uses the version 7 extended datatypes.
- reply_json(+JSONTerm) is det
- reply_json(+JSONTerm, +Options) is det
- Formulate a JSON HTTP reply. See json_write/2 for details.
The processed options are listed below. Remaining options are
forwarded to json_write/3.
- content_type(+Type)
- The default
Content-type
isapplication/json; charset=UTF8
.charset=UTF8
should not be required because JSON is defined to be UTF-8 encoded, but some clients insist on it. - status(+Code)
- The default status is 200. REST API functions may use other values from the 2XX range, such as 201 (created).
- json_object(+As)
- One of
term
(classical json representation) ordict
to use the new dict representation. If omitted and Term is a dict,dict
is assumed. SWI-Prolog Version 7.
- reply_json_dict(+JSONTerm) is det
- reply_json_dict(+JSONTerm, +Options) is det
- As reply_json/1 and reply_json/2, but assumes the new dict based data representation. Note that this is the default if the outer object is a dict. This predicate is needed to serialize a list of objects correctly and provides consistency with http_read_json_dict/2 and friends.