opium_kernel

Sinatra like web toolkit based on Lwt + Cohttp
README

Executive Summary

Sinatra like web toolkit for OCaml based on cohttp & lwt

Design Goals

  • Opium should be very small and easily learnable. A programmer should
    be instantly productive when starting out.

  • Opium should be extensible using independently developed plugins. This is a
    Rack inspired mechanism borrowed from Ruby. The middleware mechanism in
    Opium is called Rock.

  • It should maximize use of creature comforts people are used to in
    other languages. Such as sexplib, fieldslib, a decent
    standard library.

Installation

Stable

The latest stable version is available on opam

$ opam install opium

Master

If you'd like to live on the bleeding edge (which is sometimes more stable than
stable)

$ opam pin add opium --dev-repo

Examples

All examples are built once the necessary dependencies are installed.
$ dune build @examples will compile all examples. The binaries are located in
_build/default/examples/

Hello World

Here's a simple hello world example to get your feet wet:

$ cat hello_world.ml

open Opium.Std

type person = {
  name: string;
  age: int;
}

let json_of_person { name ; age } =
  let open Ezjsonm in
  dict [ "name", (string name)
       ; "age", (int age) ]

let print_param = put "/hello/:name" begin fun req ->
  `String ("Hello " ^ param req "name") |> respond'
end

let print_person = get "/person/:name/:age" begin fun req ->
  let person = {
    name = param req "name";
    age = "age" |> param req |> int_of_string;
  } in
  `Json (person |> json_of_person) |> respond'
end

let _ =
  App.empty
  |> print_param
  |> print_person
  |> App.run_command

compile with:

$ ocamlbuild -pkg opium.unix hello_world.native

and then call

./hello_world.native &
curl http://localhost:3000/person/john_doe/42

You should see a JSON message.

Middleware

The two fundamental building blocks of opium are:

  • Handlers: Rock.Request.t -> Rock.Response.t Lwt.t

  • Middleware: Rock.Handler.t -> Rock.Handler.t

Almost every all of opium's functionality is assembled through various
middleware. For example: debugging, routing, serving static files,
etc. Creating middleware is usually the most natural way to extend an
opium app.

Here's how you'd create a simple middleware turning away everyone's
favourite browser.

open Opium.Std

(* don't open cohttp and opium since they both define
   request/response modules*)

let is_substring ~substring =
  let re = Re.compile (Re.str substring) in
  Re.execp re

let reject_ua ~f =
  let filter handler req =
    match Cohttp.Header.get (Request.headers req) "user-agent" with
    | Some ua when f ua ->
      `String ("Please upgrade your browser") |> respond'
    | _ -> handler req in
  Rock.Middleware.create ~filter ~name:"reject_ua"

let _ =
  App.empty
  |> get "/" (fun _ -> `String ("Hello World") |> respond')
  |> middleware (reject_ua ~f:(is_substring ~substring:"MSIE"))
  |> App.cmd_name "Reject UA"
  |> App.run_command

Compile with:

$ ocamlbuild -pkg opium.unix middleware_ua.native

Here we also use the ability of Opium to generate a cmdliner term to run your
app. Run your executable with the -h to see the options that are available to
you. For example:

# run in debug mode on port 9000
$ ./middleware_ua.native -p 9000 -d
Install
Published
21 Mar 2019
Sources
opium-v0.17.1.tbz
md5=37bc9bffd5fad51a343b7ff202df637b
Dependencies
alcotest
with-test
re
>= "1.3.0"
ppx_sexp_conv
>= "v0.9.0"
ppx_fields_conv
>= "v0.9.0"
sexplib
>= "v0.9.0"
fieldslib
>= "v0.9.0"
base64
>= "2.0.0"
ezjsonm
>= "0.4.0" & < "1.2.0"
cohttp-lwt
>= "0.99.0"
cohttp
>= "0.99.0"
ocaml
>= "4.04.1"
Reverse Dependencies
opium
>= "0.16.0" & < "0.19.0"