aboutsummaryrefslogtreecommitdiff
path: root/gn3-guile/web/webserver.scm
diff options
context:
space:
mode:
authorPjotr Prins2023-07-06 10:26:48 -0500
committerPjotr Prins2023-07-06 10:26:48 -0500
commit00832daae019b7c4b3f651426231634dd11ed3b4 (patch)
tree1bf1c2f576745648ba299efad4e98a94ab146da9 /gn3-guile/web/webserver.scm
parent8332a0c3b4d736a600699cf1668ef486082ebc88 (diff)
downloadgenenetwork3-00832daae019b7c4b3f651426231634dd11ed3b4.tar.gz
guile server: switching to fiber web
Diffstat (limited to 'gn3-guile/web/webserver.scm')
-rwxr-xr-xgn3-guile/web/webserver.scm66
1 files changed, 56 insertions, 10 deletions
diff --git a/gn3-guile/web/webserver.scm b/gn3-guile/web/webserver.scm
index 7809661..2624125 100755
--- a/gn3-guile/web/webserver.scm
+++ b/gn3-guile/web/webserver.scm
@@ -8,15 +8,21 @@
;; Note that this is a single blocking thread server right now.
(use-modules (json)
- (web server)
+ (ice-9 match)
+ (ice-9 format)
+ (srfi srfi-1)
+ (srfi srfi-26)
+ (web http)
(web request)
(web response)
- (web uri))
+ (web uri)
+ (fibers web server)
+ )
(define (get-version-str)
"2.0")
-(define info-list (scm->json-string `(
+(define info-list `(
("name" . "GeneNetwork REST API")
("version" . ,(get-version-str))
("comment" . "This is the official REST API for the GeneNetwork service hosted at https://genenetwork.org/")
@@ -27,11 +33,7 @@
"https://genenetwork.org/api/v2/populations/"
"https://genenetwork.org/api/v2/datasets/"
)
- ))))
-
-(define (get-gn-info-str)
- info-list
- )
+ )))
(define (get-species-str)
(scm->json-string '(("Mus_musculus" . (("id" . "mouse" )
@@ -39,7 +41,9 @@
("Rattus_norvegicus" . (("id" . "rat")
("api" . "https://genenetwork.org/api/v2/rat/")))
)))
-
+(define (get-species-api-str)
+ (scm->json-string #("https://genenetwork.org/api/v2/mouse/"
+ "https://genenetwork.org/api/v2/rat/")))
;; ---- REST API web server handler
@@ -54,6 +58,10 @@
(values '((content-type . (application/json)))
(get-species-str)
))
+ ((member path (list "/species/api/"))
+ (values '((content-type . (application/json)))
+ (get-species-api-str)
+ ))
((member path (list "/"))
(values '((content-type . (application/json)))
(get-gn-info-str)
@@ -66,6 +74,43 @@
(string-append "Resource not found: "
(uri->string (request-uri request)))))
+(define (render-json json)
+ (list '((content-type . (application/json)))
+ (lambda (port)
+ (scm->json json port))))
+
+(define (controller request body)
+ (match-lambda
+ (('GET)
+ (render-json info-list))
+ (('GET "version")
+ (render-json (get-version-str)))))
+
+(define (request-path-components request)
+ (split-and-decode-uri-path (uri-path (request-uri request))))
+
+(define (handler request body)
+ (format #t "~a ~a\n"
+ (request-method request)
+ (uri-path (request-uri request)))
+ (apply values
+ ((controller request body)
+ (cons (request-method request)
+ (request-path-components request)))))
+
+(define (start-web-server address port)
+ (format (current-error-port)
+ "GN REST API web server listening on http://~a:~a/~%"
+ address port)
+ ;; Wrap handler in another function to support live hacking via the
+ ;; REPL. If handler is passed as is and is then redefined via the
+ ;; REPL, the web server will still be using the old handler. The
+ ;; only way to update the handler reference held by the web server
+ ;; would be to restart the web server.
+ (run-server (cut handler <> <>)
+ #:addr (inet-pton AF_INET address)
+ #:port port))
+
(define (main args)
(write (string-append "Starting Guile REST API " (get-version-str) " server!"))
(write args)
@@ -73,4 +118,5 @@
(let ((listen (inexact->exact (string->number (car (cdr args))))))
(display `("listening on" ,listen))
;; (write listen)
- (run-server hello-world-handler 'http `(#:port ,listen))))
+ ; (run-server hello-world-handler 'http `(#:port ,listen))))
+ (start-web-server "127.0.0.1" listen)))