├── .gitignore ├── .ocamlformat ├── LICENSE ├── README.md ├── dream-routes.opam ├── dune-project ├── esy.json └── src ├── bin ├── dune └── main.ml └── lib ├── dream_routes.ml ├── dream_routes.mli └── dune /.gitignore: -------------------------------------------------------------------------------- 1 | *.install 2 | _esy 3 | .vscode 4 | node_modules 5 | esy.lock 6 | -------------------------------------------------------------------------------- /.ocamlformat: -------------------------------------------------------------------------------- 1 | version = 0.18.0 2 | profile = conventional 3 | 4 | leading-nested-match-parens = false 5 | align-constructors-decl = true 6 | align-variants-decl = true 7 | space-around-variants = false 8 | space-around-arrays = false 9 | break-before-in = auto 10 | break-infix = fit-or-vertical 11 | break-separators = after 12 | space-around-records = true 13 | break-cases = all 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Ulrik Strid 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dream Routes 2 | 3 | Define your [Dream](https://aantron.github.io/dream/) router with [Routes](https://anuragsoni.github.io/routes/). 4 | 5 | Example based on Dream's [3-router](https://github.com/aantron/dream/tree/master/example/3-router#files): 6 | 7 | ```ocaml 8 | let () = 9 | Dream.run 10 | @@ Dream.logger 11 | @@ Dream_routes.routes Routes.[ 12 | Dream_routes.get @@ empty @--> (fun _request -> 13 | Dream.html "Good morning, world!"); 14 | 15 | Dream_routes.get @@ s "echo" / int /? nil @--> (fun integer _request -> 16 | Dream.html @@ Printf.sprintf "integer: %i" integer); 17 | 18 | Dream_routes.get @@ s "echo" / str /? nil @--> (fun word _request -> 19 | Dream.html word); 20 | ] 21 | @@ Dream.not_found 22 | ``` 23 | -------------------------------------------------------------------------------- /dream-routes.opam: -------------------------------------------------------------------------------- 1 | # This file is generated by dune, edit dune-project instead 2 | opam-version: "2.0" 3 | version: "1.0.0" 4 | synopsis: "Define your Dream router with Routes" 5 | description: "A middleware to define a Dream router with the Routes library" 6 | maintainer: ["ulrik.strid@outlook.com"] 7 | authors: ["Ulrik Strid"] 8 | license: "BSD3" 9 | homepage: "https://github.com/ulrikstrid/dream-routes" 10 | bug-reports: "https://github.com/ulrikstrid/dream-routes/issues" 11 | depends: [ 12 | "dune" {>= "2.9"} 13 | "dream" 14 | "routes" 15 | "odoc" {with-doc} 16 | ] 17 | build: [ 18 | ["dune" "subst" "--root" "."] {dev} 19 | [ 20 | "dune" 21 | "build" 22 | "-p" 23 | name 24 | "-j" 25 | jobs 26 | "--promote-install-files" 27 | "false" 28 | "@install" 29 | "@runtest" {with-test} 30 | "@doc" {with-doc} 31 | ] 32 | ["dune" "install" "-p" name "--create-install-files" name] 33 | ] 34 | dev-repo: "git+https://github.com/ulrikstrid/dream-routes.git" 35 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.9) 2 | 3 | (name dream-routes) 4 | 5 | (version 1.0.0) 6 | 7 | (generate_opam_files true) 8 | 9 | (source 10 | (github ulrikstrid/dream-routes)) 11 | 12 | (license BSD3) 13 | 14 | (authors "Ulrik Strid") 15 | 16 | (maintainers "ulrik.strid@outlook.com") 17 | 18 | (package 19 | (name dream-routes) 20 | (synopsis "Define your Dream router with Routes") 21 | (description 22 | "A middleware to define a Dream router with the Routes library") 23 | (depends dream routes)) 24 | -------------------------------------------------------------------------------- /esy.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dream-routes", 3 | "version": "1.0.0", 4 | "esy": { 5 | "build": ["dune build -p #{self.name}"] 6 | }, 7 | "scripts": { 8 | "start": "dune exec src/bin/main.exe" 9 | }, 10 | "dependencies": { 11 | "@opam/routes": "*", 12 | "@opam/dream": "*", 13 | "ocaml": ">=4.8.0" 14 | }, 15 | "devDependencies": { 16 | "@opam/ocaml-lsp-server": "*", 17 | "@opam/ocamlformat": "*", 18 | "@opam/odoc": "*" 19 | }, 20 | "resolutions": { 21 | "@opam/conf-libev": "esy-packages/libev:package.json#0b5eb6685b688649045aceac55dc559f6f21b829" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main) 3 | (public_name router_test) 4 | (libraries dream-routes dream routes)) 5 | -------------------------------------------------------------------------------- /src/bin/main.ml: -------------------------------------------------------------------------------- 1 | (** 2 | * Copyright 2021 ulrik. All rights reserved. 3 | * Use of this source code is governed by a BSD-style 4 | * license that can be found in the LICENSE file. 5 | *) 6 | 7 | let () = 8 | Dream.run 9 | @@ Dream.logger 10 | @@ Dream_routes.routes Routes.[ 11 | Dream_routes.get @@ empty @--> (fun _request -> 12 | Dream.html "Good morning, world!"); 13 | 14 | Dream_routes.get @@ s "echo" / int /? nil @--> (fun integer _request -> 15 | Dream.html @@ Printf.sprintf "integer: %i" integer); 16 | 17 | Dream_routes.get @@ s "echo" / str /? nil @--> (fun word _request -> 18 | Dream.html word); 19 | ] 20 | @@ Dream.not_found 21 | -------------------------------------------------------------------------------- /src/lib/dream_routes.ml: -------------------------------------------------------------------------------- 1 | (** 2 | * Copyright 2021 ulrik. All rights reserved. 3 | * Use of this source code is governed by a BSD-style 4 | * license that can be found in the LICENSE file. 5 | *) 6 | 7 | let to_router method_ routes = 8 | routes 9 | |> List.filter (fun (m, _) -> m = method_) 10 | |> List.map snd 11 | |> Routes.one_of 12 | 13 | type route = Dream.method_ * Dream.handler Routes.route 14 | 15 | let routes (routes : route list) = 16 | let get_router = to_router `GET routes in 17 | let post_router = to_router `POST routes in 18 | let put_router = to_router `PUT routes in 19 | let delete_router = to_router `DELETE routes in 20 | let patch_router = to_router `PATCH routes in 21 | 22 | fun next_handler (request : Dream.request) -> 23 | let target = Dream.target request in 24 | let handler = 25 | match Dream.method_ request with 26 | | `GET -> Routes.match' get_router ~target 27 | | `POST -> Routes.match' post_router ~target 28 | | `PUT -> Routes.match' put_router ~target 29 | | `DELETE -> Routes.match' delete_router ~target 30 | | `PATCH -> Routes.match' patch_router ~target 31 | | _ -> None in 32 | match handler with 33 | | Some handler -> handler request 34 | | None -> next_handler request 35 | 36 | let get route = (`GET, route) 37 | 38 | let post route = (`POST, route) 39 | 40 | let put route = (`PUT, route) 41 | 42 | let delete route = (`DELETE, route) 43 | 44 | let patch route = (`PATCH, route) 45 | -------------------------------------------------------------------------------- /src/lib/dream_routes.mli: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright 2021 ulrik. All rights reserved. 3 | * Use of this source code is governed by a BSD-style 4 | * license that can be found in the LICENSE file. 5 | *) 6 | 7 | type route 8 | (** Internal route definition *) 9 | 10 | val routes : route list -> Dream.middleware 11 | (** 12 | Middleware that takes a list of route definitions and checks for a match. 13 | If there is no match the next handler will be called. 14 | 15 | You can read more about how to define routes {{:https://anuragsoni.github.io/routes/} [here]} 16 | 17 | Example usage based on the {{:https://github.com/aantron/dream/tree/master/example/3-router#files} [router example]}: 18 | {[ 19 | let () = 20 | Dream.run 21 | @@ Dream.logger 22 | @@ Dream_routes.routes Routes.[ 23 | Dream_routes.get @@ empty @--> (fun _request -> 24 | Dream.html "Good morning, world!"); 25 | 26 | Dream_routes.get @@ s "echo" / int /? nil @--> (fun integer _request -> 27 | Dream.html @@ Printf.sprintf "integer: %i" integer); 28 | 29 | Dream_routes.get @@ s "echo" / str /? nil @--> (fun word _request -> 30 | Dream.html word); 31 | ] 32 | @@ Dream.not_found 33 | ]} 34 | *) 35 | 36 | val get : Dream.handler Routes.route -> route 37 | (** Creates a route that matches on the GET method *) 38 | 39 | val post : Dream.handler Routes.route -> route 40 | (** Creates a route that matches on the POST method *) 41 | 42 | val put : Dream.handler Routes.route -> route 43 | (** Creates a route that matches on the PUT method *) 44 | 45 | val delete : Dream.handler Routes.route -> route 46 | (** Creates a route that matches on the DELETE method *) 47 | 48 | val patch : Dream.handler Routes.route -> route 49 | (** Creates a route that matches on the PATCH method *) 50 | -------------------------------------------------------------------------------- /src/lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name dream_routes) 3 | (public_name dream-routes) 4 | (libraries dream routes)) 5 | --------------------------------------------------------------------------------