diff options
author | Arun Isaac | 2021-12-30 16:43:57 +0530 |
---|---|---|
committer | Arun Isaac | 2021-12-30 16:43:57 +0530 |
commit | 68f478625dbec55c5d78d5896d60016e140150a8 (patch) | |
tree | f4eb98a277f43d5cafc14c6c847ed7e3ec70e736 | |
parent | 87166ff87ee0c13611f28a0dfab75a52a13bdd32 (diff) | |
download | kolam-68f478625dbec55c5d78d5896d60016e140150a8.tar.gz kolam-68f478625dbec55c5d78d5896d60016e140150a8.tar.lz kolam-68f478625dbec55c5d78d5896d60016e140150a8.zip |
kolam: Implement HTTP client.
* kolam/http.scm: Import (srfi srfi-26), (web client), (web
response) and (kolam utils).
(variables->alist, graphql-http-response): New functions.
(graphql-http-get, graphql-http-post): New public functions.
-rw-r--r-- | kolam/http.scm | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/kolam/http.scm b/kolam/http.scm index 2098ef1..9efbd60 100644 --- a/kolam/http.scm +++ b/kolam/http.scm @@ -19,13 +19,19 @@ (define-module (kolam http) #:use-module (rnrs io ports) + #:use-module (srfi srfi-26) #:use-module (ice-9 match) + #:use-module (web client) #:use-module (web request) + #:use-module (web response) #:use-module (web uri) #:use-module (json) #:use-module (kolam graphql) #:use-module (kolam parse) - #:export (graphql-handler)) + #:use-module (kolam utils) + #:export (graphql-handler + graphql-http-get + graphql-http-post)) (define transcoder (make-transcoder (utf-8-codec) 'none 'raise)) @@ -62,3 +68,60 @@ run-server from guile's (web server)." "query")) (('document operations ...) `(("data" . ,(map evaluator operations)))))))))) + +(define (variables->alist variables) + "Convert VARIABLES into an association list to be embedded into the +GraphQL request." + (map (match-lambda + ((key . value) + (cons (keyword->symbol key) + value))) + (pairify variables))) + +(define (graphql-http-get uri document . variables) + "Send GraphQL query as specified in GraphQL DOCUMENT to graphql +endpoint URI. The GET HTTP method is used. VARIABLES must be a list of +variables to send with the query. It must be of the form (name value +...) where NAME must be a keyword. For example, (#:spam 1 #:ham +\"bacon\" #:eggs 2)." + (call-with-values + (cut http-get + (string-append uri + "?query=" + (uri-encode (scm->graphql-string document)) + "&" + "variables=" + (uri-encode (scm->json-string + (variables->alist variables)))) + #:streaming? #t) + graphql-http-response)) + +(define (graphql-http-post uri document . variables) + "Send GraphQL query as specified in GraphQL DOCUMENT to graphql +endpoint URI. The POST HTTP method is used. VARIABLES must be a list +of variables to send with the query. It must be of the form (name +value ...) where NAME must be a keyword. For example, (#:spam 1 #:ham +\"bacon\" #:eggs 2)." + (call-with-values + (cut http-post + uri + #:body (scm->json-string + (cons (cons 'query (scm->graphql-string document)) + (match variables + (() '()) + (_ (cons 'variables (variables->alist variables)))))) + #:streaming? #t) + graphql-http-response)) + +(define (graphql-http-response response port) + "Return GraphQL response data from HTTP RESPONSE and response body +read from PORT. Raise errors, if any." + (unless (and (>= (response-code response) 200) + (< (response-code response) 300)) + (error "GraphQL query failed with non-2xx status code:" + response (get-string-all port))) + (let ((response-alist (json->scm port))) + (cond + ((assoc-ref response-alist "errors") + => (cut error "GraphQL query failed with errors:" <>)) + (else (assoc-ref response-alist "data"))))) |