Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kkazuo/horned_worm
An easy functional Web app micro framework.
https://github.com/kkazuo/horned_worm
async horned-worm http ocaml webservice
Last synced: about 14 hours ago
JSON representation
An easy functional Web app micro framework.
- Host: GitHub
- URL: https://github.com/kkazuo/horned_worm
- Owner: kkazuo
- License: mit
- Created: 2017-10-12T18:02:55.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2020-11-05T14:21:20.000Z (about 4 years ago)
- Last Synced: 2023-03-11T06:57:58.860Z (over 1 year ago)
- Topics: async, horned-worm, http, ocaml, webservice
- Language: OCaml
- Homepage:
- Size: 32.2 KB
- Stars: 23
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.MIT
Awesome Lists containing this project
README
# Horned_worm
A functional Web app server.
Greatly inspired by [Suave.IO](https://suave.io) and [GIRAFFE](https://github.com/dustinmoris/Giraffe) of F#, this is OCaml implementation.
> Sphingids are some of the faster flying insects; some are capable of flying at over 5.3 m/s (12 miles per hour). --- [Wikipedia](https://en.wikipedia.org/wiki/Sphingidae)
## Web Parts
### path
```ocaml
let app =
path "/hello"
>=> text "hello, world"
```### path_ci
```ocaml
let app =
path_ci "/hello"
>=> text "hello, world"
```### path_starts
```ocaml
let app =
path_starts "/hello/"
>=> text "hello, world"
```### path_starts_ci
```ocaml
let app =
path_starts_ci "/hello/"
>=> text "hello, world"
```### path_regex
```ocaml
let app =
path_regex "/hello/wo{3}rld"
>=> text "hello, world"
```### path_scanf
```ocaml
let app =
path_scanf "/%d/%d" begin fun x y ->
text @@ Printf.sprintf "hello, %d" (x + y)
end
```### meth
```ocaml
let app =
meth `GET
>=> text "hello, world"
```### filter_p
```ocaml
let app =
filter_p (fun ctx -> true)
>=> text "text."
```### path_p
```ocaml
let app =
path_p (fun path -> true)
>=> text "text."
```### choose
```ocaml
let app =
choose
[ meth `GET
>=> choose
[ path "/a" >=> text "hello, GET a"
; path "/b" >=> text "hello, GET b"
]
; meth `POST >=> text "hello, POST"
]
```### log
```ocaml
let app =
log Logs.err (fun ctx m -> m "error message.")
>=> text "text."
```### set_mime_type
```ocaml
let app =
set_mime_type "text/plain; charset=utf-8"
>=> text "text."
```### set_status
```ocaml
let app =
set_status `Bad_request
>=> text "text."
```### set_header
```ocaml
let app =
set_header "x-test" "my test header"
>=> text "text."
```### set_header_unless_exists
```ocaml
let app =
set_header_unless_exists "x-test" "my test header"
>=> text "text."
```### add_header
```ocaml
let app =
add_header "x-test" "my test header"
>=> text "text."
```### use_cookie
```ocaml
let app =
use_cookie
>=> text "text."
```### set_cookie
```ocaml
let app =
set_cookie "key" "value"
>=> text "text."
```### browse
```ocaml
let app =
browse "/etc"
```### browse_file
```ocaml
let app =
browse_file "/etc" "/hosts"
```### text
```ocaml
let app =
text "hello, world."
```### texts
```ocaml
let app =
texts [ "hello"
; ", world."
]
```### json
```ocaml
let app =
json (`Assoc [ "hello", `String "world"
; "key", `Int 1 ])
```### respond_string
```ocaml
let app =
respond_string "string"
```### respond_strings
```ocaml
let app =
respond_strings [ "string"; "string" ]
```### respond_file
```ocaml
let app =
respond_file "/etc/hosts"
```### simple_cors
```ocaml
let app =
simple_cors
>=> text "text."
```### secure_headers
```ocaml
let app =
secure_headers
>=> text "text."
```### web_server
- Web_part.t Web app
- int Listening port### run_web_server
- app Web_part.t
Simple Web_part.t runner.
## Compose your own parts
```ocaml
let yourapp : Web_part.t =
fun next ctx ->
(* your work here *)
if (* should continue *) then
let modified_ctx = ctx in
begin
set_header "a" "b" >=>
set_header "x" "y"
end next modified_ctx
else
Web_part.fail
```## How to start
Example:
```ocaml
open Core
open Async
open Horned_wormlet app =
choose
[ meth `GET >=> choose
[ path "/" >=> text "hello, world"
; path "/cookie" >=> use_cookie >=> begin
let key = "test" in
fun next ctx ->
let v = Option.value Http_context.(cookie ctx ~key)
~default:"hello cookie" in
begin
set_cookie key (v ^ "!") >=>
text v
end next ctx
end
; path_scanf "/%d/%d" begin fun x y ->
text (sprintf "%d + %d = %d" x y (x + y))
end
; path_scanf "/json/%s" begin fun s ->
json (`Assoc ["hello", `String s])
end
]
; meth `POST >=> path "/" >=> text "hello, POST"
]let () =
run_web_server app
```## Install
opam install horned_worm
## Status
- alpha
Todo:
- more predefined Web parts.
- needs query parm receiver.
- builtin websocket supports.