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, cow, a decent
    standard library.

Installation

NOTE: At this point there's a good chance this library will only
work against cohttp master. Once cohttp 1.0 is released then this
library will always be developed against OPAM version.

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 (cow).
$ make will compile all examples. The binaries are located in
_build/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 Deferred.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
open Opium_misc

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

let is_substring ~substring s =
  Option.is_some (String.substr_index s ~pattern:substring)

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 req -> `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
31 Jul 2017
Sources
v0.16.0.tar.gz
md5=4905ce17175c91e47458fccfd6a8885f
Dependencies
cow
with-test & >= "0.10.0"
uri
< "2.0.0"
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" & < "3.0.0"
ezjsonm
>= "0.4.0" & < "1.2.0"
cohttp-lwt
>= "0.99.0"
cohttp
>= "0.99.0"
jbuilder
>= "1.0+beta7"
ocaml
>= "4.02.3"
Reverse Dependencies
opium
>= "0.16.0" & < "0.19.0"