Next: How to pass some additional request context?, Previous: Middleware composition, Up: Basic concepts
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: How to pass some additional request context?, Previous: Middleware composition, Up: Basic concepts