(rontolisp) docs
← Reference

Ring adapter (ring.adapter.rontolisp)

ring.adapter.rontolisp/run-server serves a Ring handler -- a function of a request map answering a response map -- on the target's own inbound HTTP transport. It is built in: require it like clojure.string. The one source runs on every transport the Clack backend :server :rontolisp serves (Clack): both adapters call the same transport code.

TargetBuildTransport
Interpreterrontolisp app.clja socket the program binds (:port, :host)
JVM-o App.class, -o app.jarthe same socket server
Servlet war-o app.warthe container owns the port; run-server registers the handler and returns
WASM component-o app.wasm --component, run with wasmtime servethe host owns the socket; run-server returns at once
WASM reactor-o app.wasm --no-wasithe host calls the handle-request export (the reactor build)

A plain Preview 1 module (-o app.wasm) has no incoming connections: it compiles, and run-server signals that serving requires --component when it runs.

NameExampleResult
ring.adapter.rontolisp/run-server(run-server handler {:port 3000})blocks; :join? false answers the server
$ cat app.clj
(ns app (:require [ring.adapter.rontolisp :refer [run-server]]))

(defn handler [{:keys [request-method uri]}]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body (str (name request-method) " " uri "\n")})

(run-server handler {:port 3000 :host "127.0.0.1"})
$ rontolisp app.clj &
$ curl http://127.0.0.1:3000/hello
get /hello

The request map

KeyValue
:request-methodthe method as a lower-case keyword: :get, :post, ...
:urithe request path as sent (not percent-decoded), without the query
:query-stringthe text after ?, or nil
:headersa map of lower-case header names to values; repeated headers joined with ", "
:server-name, :server-portfrom the Host header, else the listening address
:remote-addrthe peer address; nil on the component and on a reactor whose host sends none
:scheme:http or :https
:protocol"HTTP/1.1"
:content-type, :content-lengthfrom the headers, nil when absent
:bodya java.io.InputStream of the request body's octets, empty for a request without one

Read :body with .read, slurp (in the charset :encoding names, UTF-8 by default), clojure.java.io/reader, line-seq, clojure.java.io/copy or a java.io.InputStreamReader, on every backend; a binary upload reads octet for octet. The stream is buffered, so a read never waits on the network. Its class is Ring's Jetty adapter's, org.eclipse.jetty.ee9.nested.HttpInput, and as there a close leaves it readable: after slurp a later read answers the end of the body. Answered as the response :body, or sent on as a rontolisp.http-client request :body, it is its octets.

The response map

KeyValue
:statusan integer; 200 when absent
:headersa map of header names (strings or keywords) to a string, or to a seq of strings sent as one header line each
:bodya string, a seq whose members are sent through str, a reader or input stream (read to its end and closed), a java.io.File (its bytes as they are), or nil

A handler that answers anything but a map, or a body of any other kind, signals; the transport answers 500. So does a java.io.File naming no file the program can read: the WebAssembly serving transports (wasmtime serve, the reactor) have no file system, so a file is served on the interpreter, the JVM and a war; a byte stream over a resource the program carries is served everywhere. The response builders, file-response and resource-response among them, and the parameter middleware are the built-in Ring utilities.

Cloudflare Workers

A Worker calls the handle-request export, so the reactor build deploys as one with no change to the source. --emit-js-glue writes the JavaScript half beside the module:

$ rontolisp app.clj -o src/worker.wasm --no-wasi --optimize=size --emit-js-glue
$ cat src/index.js
import module from "./worker.wasm";
import { worker } from "./worker.js";

export default worker(module);
$ npx wrangler dev      # http://localhost:8787
$ npx wrangler deploy

:port and :host are not read there. A complete project, with wrangler.jsonc and a build.sh over the same Ring example the other targets build, is examples/cloudflare-workers/ring-hello-one-source/.