Home Up Back Forward Leave Message


Overview

The code is available for download from:

This code is also making use of the following:

Please note that I'm making use of Guile/Scheme, so for other scheme implementation there will be some rework involved specifically for the web server stuff and some of the build in functions that Guile has that other schemes either doesn't have or doesn't implement in exactly the same way.

JSON handling in Guile/Scheme

The JSON module that is mentioned above provides the JSON handling for the server and client. But because they don't handle association lists at all I've added some basic functionality to the Webserver (webserv-support.scm) to do this. The two functions to use are escm->json to convert scheme lists to JSON and esjson->scm to take JSON and generate scheme from it. For example:
    (load "webserv-support.scm")
    (define logonstr '((username . "daffy") (password . "duck)))
    (define logonjson (escm->json logonstr)) ; this will generate {"username": "daffy", "password": "duck"}
    (define andback (esjson->scm logonjson)) ; this will generate ((username . "daffy") (password . "duck))
As can be seen from the examle the conversion is extremely straight forward to either side.

HTTP handling of requests

Each function is a handler (as required by the guile-webserv module) and each handler is called with the request information, the body (in byte vector format) and the response headers. With our implementation we really don't worry at all about the request information, but the body contains the JSON structure of the call and the response headers is really to set headers for the response to the browser. The helper function getInput sets these headers for us and converts the body from JSON to list format:
    (define (getInput body rh) 
      (response-header-set rh 'content-type '(application/json))
      (response-header-set rh 'Access-Control-Allow-Origin "*")
      (esjson->scm (bytevector->string body "utf-8")))    
Seeing that JSON objects are converted to association lists in our Guile implementation we can access the fields by assoc-ref. Three helper functions will generate the output (in JSON format) and they are:

HTTP handling of calls

To handle all calls to a microservice the helper function callService is defined in the client:
    (use-modules (web uri))
    (use-modules (web client))
    (use-modules (ice-9 receive))

    (define (callService call body)
       (let* ((req (string-append "http://localhost:8080/" call))
              (tmp (receive (misc data) (http-post req #:body (esscm->json body)) data)))
            (esjson->scm tmp)))    
To post the request, the body is first converted to JSON, then http-post is called (part of modules included). This generates a multi-value return of the returned headers and the returned body. receive will catch the multi-values for us, but we are only interested in the body part (data in this case). The returned body is then converted from JSON to scheme and returned.