- Notifications
You must be signed in to change notification settings - Fork71
Sinatra like web toolkit for OCaml
License
rgrinberg/opium
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Since version 0.19.0, Opium uses httpaf. The last version that used Cohttp can be found athttps://github.com/rgrinberg/opium/tree/0.18.0
Sinatra like web toolkit for OCaml based onhttpaf &lwt
Opium should be very small and easily learnable. A programmer shouldbe instantly productive when starting out.
Opium should be extensible using independently developed plugins. This is aRack inspired mechanism borrowed from Ruby. The middleware mechanism inOpium is called
Rock.
The latest stable version is available on opam
$ opam install opium$ opam pin add rock.~dev https://github.com/rgrinberg/opium.git$ opam pin add opium.~dev https://github.com/rgrinberg/opium.gitFor theAPI documentation:
- Readthe hosted documentation for the latest version.
- Build and view the docs for version installed locally using
odig:odig doc opium.
The followingtutorials walk through various usecases of Opium:
- A Lightweight OCaml Webapp Tutorialcovers a simple webapp generating dynamic HTML on the backend andinterfacing with PostgreSQL.
Forexamples of idiomatic usage, see the./example directoryand the simple examples below.
Assuming the necessary dependencies are installed,$ dune build @example willcompile all examples. The binaries are located in_build/default/example/.
You can execute these binaries directly, though in the examples below we usedune exec to run them.
Here's a simple hello world example to get your feet wet:
$ cat hello_world.ml
openOpiummodulePerson=structtypet= {name :string;age :int }letyojson_of_tt=`Assoc ["name",`String t.name;"age",`Int t.age ]lett_of_yojsonyojson=match yojsonwith|`Assoc [ ("name",`String name); ("age",`Int age) ] -> { name; age }|_ -> failwith"invalid person json" ;;endletprint_person_handlerreq=let name=Router.param req"name"inlet age=Router.param req"age"|> int_of_stringinlet person= {Person.name; age }|>Person.yojson_of_tinLwt.return (Response.of_json person);;letupdate_person_handlerreq=letopenLwt.Syntaxinlet+ json=Request.to_json_exn reqinlet person=Person.t_of_yojson jsoninLogs.info (funm -> m"Received person: %s" person.Person.name);Response.of_json (`Assoc ["message",`String"Person saved" ]);;letstreaming_handlerreq=let length=Body.length req.Request.bodyinlet content=Body.to_stream req.Request.bodyinlet body=Lwt_stream.mapString.uppercase_ascii contentinResponse.make~body:(Body.of_stream ?length body)()|>Lwt.return;;letprint_param_handlerreq=Printf.sprintf"Hello, %s\n" (Router.param req"name")|>Response.of_plain_text|>Lwt.return;;let _=App.empty|>App.post"/hello/stream" streaming_handler|>App.get"/hello/:name" print_param_handler|>App.get"/person/:name/:age" print_person_handler|>App.patch"/person" update_person_handler|>App.run_command;;
compile and run with:
$duneexec examples/hello_world.exe&then make a request to be greeted with a JSON response
$curl http://localhost:3000/person/john_doe/42{"name":"john_doe","age":42}
The two fundamental building blocks of opium are:
- Handlers:
Request.t -> Response.t Lwt.t - Middleware:
Rock.Handler.t -> Rock.Handler.t
Almost all of opium's functionality is assembled through variousmiddleware. For example: debugging, routing, serving static files,etc. Creating middleware is usually the most natural way to extend anopium app.
Here's how you'd create a simple middleware turning away everyone'sfavourite browser.
openOpiummoduleReject_user_agent=structlet is_ua_msie=let re=Re.compile (Re.str"MSIE")inRe.execp re ;;let m=letfilterhandlerreq=matchRequest.header"user-agent" reqwith|Someuawhen is_ua_msie ua ->Response.of_plain_text~status:`Bad_request"Please upgrade your browser"|>Lwt.return|_ -> handler reqinRock.Middleware.create~filter~name:"Reject User-Agent" ;;endletindex_handler_request=Response.of_plain_text"Hello World!"|>Lwt.returnlet _=App.empty|>App.get"/" index_handler|>App.middlewareReject_user_agent.m|>App.cmd_name"Reject UA"|>App.run_command;;
Compile with:
$ dune build example/simple_middleware/main.ml
Here we also use the ability of Opium to generate a cmdliner term to run yourapp. Run your executable with-h to see the options that are available to you.For example:
#runin debug mode on port 9000$duneexec dune build example/simple_middleware/main.exe -- -p 9000 -d
About
Sinatra like web toolkit for OCaml
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.