How to create a RESTful API to the PicoLisp Database

What is a REST-API?

  • client-server model,
  • stateless protocol (no session information needed),
  • cacheability,
  • layered system,
  • uniform interface.

Creating JSON output in PicoLisp

  • Numbers,
  • Strings, delimited with double-quotes and backslash as escape symbol,
  • Boolean (true or false)
  • Arrays using square bracket notation with comma-separated elements,
  • Objects as a collection of name-value pairs, where the names are also strings,
  • null as empty value.
  • checkJson (X Item),
  • parseJson (Str),
  • readJson (),
  • printJson (Item).
: (setq A 
'( ( name . "Smith" )
( age . 25)
( address
( street . "21 2nd Street")
( city . "New York")
( state . "NY" )
( zip . 10021 ) ) ) )
: (printJson A)
{"name": "Smith", "age": 25, "address": {"street": "21 2nd Street", "city": "New York", "state": "NY", "zip": 10021}}

Creating a cons-pair list

$ pil family.l -family~main +
family:
family: (getl '{A1})
-> ((({A2} {A4}) . kids) ("Margaret Rose" . nm) ({A3} . mate) ({A11} . ma) ({A33} . pa) (705091 . dat) ("Countess of Snowdon" . job))
  1. Key and value are reversed. instead of ( "Margaret Rose" . nm ) we need ( nm . "Margaret Rose" ).
  2. The symbol names at mate, ma, pa and so on should be replaced by the person's names.
  3. The date 705091 should be formatted.

Changing CAR and CDR in the cons pair

: (cons 1 2)
-> (1 . 2)
(mapcar
'((X)
(cons (cdr X) (car X)) )
(getl This )
family: (mapcar '((X) (cons (cdr X) (car X))) (getl '{A1}))
-> ((kids {A2} {A4}) (nm . "Margaret Rose") (mate . {A3}) (ma . {A11}) (pa . {A33}) (dat . 705091) (job . "Countess of Snowdon"))

Formatting the list

  • (({A2} {A4}) . kids)
  • ("Margaret Rose" . nm)
  • ({A3} . mate)
  • ({A11} . ma)
  • ({A33} . pa)
  • (705091 . dat)
  • ("Countess of Snowdon" . job)
(cond
((num? V) (datStr V))
(cond
((num? V) (datStr V))
((isa '+Person V) (; V nm))
(mapcar '((This) (: nm)) V)
(cond
((num? V) (datStr V))
((isa '+Person V) (; V nm))
((pair V) (mapcar '((This) (: nm)) V) )
(cond
((num? V) (datStr V))
((isa '+Person V) (; V nm))
((pair V) (mapcar '((This) (: nm)) V) )
(T V) )

Bringing it together

  1. get the list with (getl This)
  2. apply mapcar to build a new cons pair
  3. before we set the car, we modify it depending on the result of cond.
(mapcar 
'((X)
(cons (cdr X)
(let V (car X)
(cond
((pair V)
(mapcar '((This) (: dat)) V) )
((num? V) (datStr V)) # Can only be date
((isa '+Person V) (; V nm))
(T V) ) ) ) )
(getl This) )

Convert to JSON and return it!

family: (httpHead "application/json" 0)HTTP/1.0 200 OK
Server: PicoLisp
Date: Sun, 17 Oct 2021 14:44:31 GMT
Cache-Control: max-age=0
Cache-Control: private, no-store, no-cache
Content-Type: application/json
(httpHead "application/json" 0)
(ht:Out *Chunked
(printJson
...
(allowed NIL
"@lib.css" "!person.json" )
...(de person.json (This)
(httpHead "application/json" 0)
(ht:Out *Chunked
(printJson
...
...
$ pil family-rest.l -family~main -go +

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mia Temma

Mia Temma

These are cross-posts from my blog https://picolisp-explored.com. I’m writing about PicoLisp for beginners. Welcome!