HTTP
HTTP/1.1 client and server functionality.
(import (sigil http))Client
http-get
Make an HTTP GET request.
(let ((response (http-get "https://example.com/")))
(display (http-response-body response)))
;; With custom headers
(http-get "https://api.example.com/data"
'(("Authorization" . "Bearer token123")))http-post
Make an HTTP POST request.
;; Form data (default Content-Type: application/x-www-form-urlencoded)
(http-post "https://example.com/login"
"username=alice&password=secret")
;; JSON body
(import (sigil json))
(http-post "https://api.example.com/users"
(json-encode #{ name: "Alice" })
'(("Content-Type" . "application/json")))http-put / http-delete
(http-put "https://api.example.com/users/1"
(json-encode #{ name: "Bob" })
'(("Content-Type" . "application/json")))
(http-delete "https://api.example.com/users/1")http-request
Low-level request function for any HTTP method.
(http-request 'PATCH "https://api.example.com/resource"
'(("Content-Type" . "application/json"))
(json-encode #{ status: "active" }))Response Accessors
(let ((response (http-get "https://example.com/")))
(http-response-status response) ; => 200
(http-response-headers response) ; => #{ content-type: "text/html" ... }
(http-response-body response)) ; => "<html>..."URL Parsing
(let ((url (parse-url "https://example.com:8080/path?query=1")))
(url-scheme url) ; => "https"
(url-host url) ; => "example.com"
(url-port url) ; => 8080
(url-path url) ; => "/path"
(url-query url)) ; => "query=1"Server
http-serve
Start a blocking HTTP server.
(http-serve 8080
(lambda (request)
(http-response/html 200 "<h1>Hello!</h1>")))Request Accessors
(lambda (req)
(http-request-method req) ; => 'GET, 'POST, etc.
(http-request-path req) ; => "/users/123"
(http-request-query req) ; => "format=json" or #f
(http-request-headers req) ; => #{ content-type: "..." ... }
(http-request-body req) ; => string or #f
(http-request-header req content-type:)) ; => "application/json"Response Constructors
;; Plain text
(http-response/text 200 "Hello, World!")
;; HTML
(http-response/html 200 "<h1>Welcome</h1>")
;; JSON (auto-encodes)
(http-response/json 200 #{ status: "ok" users: #[1 2 3] })
;; Redirect
(http-response/redirect "/new-location")
(http-response/redirect "/new-location" 301) ; Permanent
;; Error
(http-response/error 500 "Internal Server Error")
;; Not Found
(http-response/not-found)Custom Response
(http-response
status: 201
headers: #{ content-type: "application/json"
x-custom-header: "value" }
body: (json-encode #{ id: 123 }))Form Parsing
;; URL-encoded form data
(let ((form (parse-form-urlencoded (http-request-body req))))
(dict-ref form username:))
;; Multipart form data (file uploads)
(let ((parts (parse-form-data req)))
(dict-ref parts file:))Server-Sent Events (SSE)
;; Single client SSE stream
(http-response/sse
(lambda (send)
(send (sse-event "message" (json-encode #{ count: 1 })))
(send (sse-data "plain text data"))))
;; Broadcast to multiple clients
(http-response/sse-broadcast channel)Status Code Constants
HTTP-OK ; 200
HTTP-CREATED ; 201
HTTP-NO-CONTENT ; 204
HTTP-MOVED-PERMANENTLY ; 301
HTTP-FOUND ; 302
HTTP-NOT-MODIFIED ; 304
HTTP-BAD-REQUEST ; 400
HTTP-UNAUTHORIZED ; 401
HTTP-FORBIDDEN ; 403
HTTP-NOT-FOUND ; 404
HTTP-INTERNAL-SERVER-ERROR ; 500Common Patterns
REST API Server
(import (sigil http)
(sigil json))
(define users #{ 1: #{ name: "Alice" } 2: #{ name: "Bob" } })
(http-serve 8080
(lambda (req)
(let ((method (http-request-method req))
(path (http-request-path req)))
(cond
;; GET /users
((and (eq? method 'GET) (string=? path "/users"))
(http-response/json 200 users))
;; GET /users/:id
((and (eq? method 'GET) (string-starts-with? path "/users/"))
(let* ((id (string->number (substring path 7 (string-length path))))
(user (dict-ref users id #f)))
(if user
(http-response/json 200 user)
(http-response/not-found))))
;; POST /users
((and (eq? method 'POST) (string=? path "/users"))
(let ((data (json-decode (http-request-body req))))
(http-response/json 201 #{ id: 3 name: (dict-ref data name:) })))
(else (http-response/not-found))))))Fetch and Process JSON API
(import (sigil http)
(sigil json))
(define (fetch-user id)
(let ((response (http-get (format "https://api.example.com/users/~a" id))))
(if (= (http-response-status response) 200)
(json-decode (http-response-body response))
#f)))
(let ((user (fetch-user 123)))
(when user
(display (dict-ref user name:))))