guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Operate upon POST request with Guile webserver


From: Ricardo Wurmus
Subject: Re: Operate upon POST request with Guile webserver
Date: Sun, 21 Aug 2022 21:47:16 +0200
User-agent: mu4e 1.8.7; emacs 28.1

Hi,

Gentoo Arch <gentoocore@firemail.cc> writes:

> I'm trying to figure out how Guile webserver works to develop a simple
> BBS  and I'm kinda stuck with POST request.
>
> My Guile script generates a form on any path and the form sends to
> "/post" path, where I can easily render content sent by the form.

Daniel already solved your immediate problem, but I wanted to show you a
common pattern many of us use to build web servers:

--8<---------------cut here---------------start------------->8---
(define* (render-html sxml #:optional (headers '()))
  (list (append '((content-type . (text/html))) headers)
        (lambda (port)
          (sxml->xml sxml port))))

(define (request-path-components request)
  (split-and-decode-uri-path (uri-path (request-uri request))))

(define (controller request body)
  (match (cons (request-method request)
               (request-path-components request))
    (('POST "api" "container" id "launch")
     (render-html `(html
                    (head (title "whatever"))
                    (body "who cares"))))
    (('PUT "api" "container" id "connect")
     ...)
    (('DELETE "api" "container" id)
     ...)
    (('GET "api" "containers")
     ...)
    (('GET "api" "container" id "info")
     ...)
    (_ (not-found (request-uri request)))))

(define (handler request body)
  (format (current-error-port)
          "~a ~a~%"
          (request-method request)
          (uri-path (request-uri request)))
  (if (getenv "DEBUG")
      (call-with-error-handling
        (lambda ()
          (apply values (controller request body))))
      (apply values (controller request body))))

(define (run-my-server port)
  (run-server handler #:port port))
--8<---------------cut here---------------end--------------->8---

The controller uses match on the method and the path, which makes for
pretty clear code.  You can bind parts of the path to variables and
operate on them.

The “values” stuff is handled in “handler” here, but it also be done
directly in the controller.

To operate on the POST payload, you’d need to parse the form data from
the body, which is available to the controller.  See also guile-webutils
for some handy tools.

Hope this helps!

-- 
Ricardo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]