A Delightful OCaml web programming library.
-
ohtml
- a fast, compiled view engine allowing you to mix HTML with OCaml code - Type safe, radix-tree based url routing engine. Use ppx to specify route path, e.g.
[%r "/store/products/:int"]
- Form handling/data upload (multipart/formdata protocol - RFC 9110 - for standards compliance and interoperability)
- CSRF form protection (Anti CSRF mechanism)
- Secure HTTP session based on encrypted cookie
- Secure HTTP session based on SQLite/Postgres/Mysql
- HTTP Cookies (RFC 6265)
- Type-safe HTTP header manipulation
- Fullly compliant (RFC 7230) HTTP chunked transfer protocol (both client and server)
- HTTP file server - host/serve static web assets such as
.css, .js, .jpg, .png
etc - HTTP/1.1 (RFC 9112) multicore/parallel server/client
- HTTPS/1.1 server/client (TLS/1.3)
- Closely aligned with
eio
io library
Hello world in Spring 1
hello.ml
open Spring
let say_hello _req = V.view ~title:"Hello Page" V.hello_v
let display_products _req =
V.products_v [ "apple"; "oranges"; "bananas" ]
|> V.view ~title:"Products Page"
let () =
Eio_main.run @@ fun env ->
Server.app_server ~on_error:raise env#clock env#net
|> Server.get [%r "/"] say_hello
|> Server.get [%r "/products"] display_products
|> Server.run_local ~port:8080
hello_v.ohtml
<span>Hello world!</span>
layout_v.ohtml
fun ~title ~body ->
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
</head>
<body>
{{ body }}
</body>
</html>
products_v.ohtml
open Spring
fun products ->
<div id=div1
class="abc ccc aaa"
disabled
{ Ohtml.attribute ~name:"hx-swap" ~value:"outerHTML" }
get=@{if true then "/products" else "/index"}
hx-sse=@"connect:/news_update">
Hello
<span>world!</span>
<h2>Products for sale</h2>
<ol>
{ List.iter (fun product ->
<li>
@{if product = "apple" then "red apple" else product}
<span>
@product<text>hello</text>
@product
</span>
</li>
) products
}
</ol>
</div>
Footnotes
-
See https://github.com/bikallem/spring/tree/main/examples/hello for full sample ↩