Next: , Previous: , Up: Basic concepts  

2.2 A middleware procedure

A middleware procedure takes three input arguments and returns two values.

(define (do-smth request body cont)
  ;; code
  (values response response-body)

request and body are standard Guile web server handler’s inputs. cont is a continuation. Here, a continuation is a procedure of two arguments: a request object and a request body, and it returns two values: a response object and a response body.

The purpose of a continuation procedure is, well, to continue the execution of the remaining middlewares in a chain, following the current one. Let’s see how to use this facility.

In general, any middleware code may want to choose among three main flows:

Middleware implementations note For naming consistency, this package suggests a middleware procedure to be named with a verb notation, not an object one. E.g log-request instead of request-logger, or authenticate-user instead of user-authenticator etc.

Let’s look at some prototype log-request middleware:

(use-modules (web request)
             (web uri))
(define (log-request request body cont)
  ;; Print request path to stdout
  (format #t "~a" (uri-path (request-uri request)))
  ;; Return the result of calling the remaining middlewares in a chain
  ;; Possibly, that would be a normal response from a router middleware
  (cont request body))

Okay, let’s say we want to log a response code. So, we need to first retrieve the response from a continuation, and then print our log message:

(use-modules (web request)
             (web uri)
             (web response)
             (scheme base))
(define (log-request-with-response-code request body cont)
  (let-values [((response response-body) (cont request body))]
    ;; assuming for this example, that response is always a (web response) object
    (format #t "~a ~a" (uri-path (request-uri request)) (response-code response))
    (values response response-body))

Next: , Previous: , Up: Basic concepts