From f0142aa1c3b4d7c2fd0b70c9e62c1ec033e445c2 Mon Sep 17 00:00:00 2001 From: Mateus Cruz Date: Mon, 5 Feb 2024 00:14:45 -0300 Subject: add basic route handling --- bin/dune | 4 +-- bin/main.ml | 27 ++++++++++++++++++++- docker-compose.yml | 2 +- dune-project | 4 +-- flake.nix | 18 +++++++------- lib/dune | 3 ++- lib/router.ml | 59 +++++++++++++++++++++++++++++++++++++++++++++ lib/router.mli | 1 + rinha.opam | 31 ++++++++++++++++++++++++ rinhadebackend.opam | 31 ------------------------ test/dune | 2 +- test/test_rinha.ml | 0 test/test_rinhadebackend.ml | 0 13 files changed, 134 insertions(+), 48 deletions(-) create mode 100644 lib/router.ml create mode 100644 lib/router.mli create mode 100644 rinha.opam delete mode 100644 rinhadebackend.opam create mode 100644 test/test_rinha.ml delete mode 100644 test/test_rinhadebackend.ml diff --git a/bin/dune b/bin/dune index 0716639..a186150 100644 --- a/bin/dune +++ b/bin/dune @@ -1,10 +1,10 @@ (executable - (public_name rinhadebackend) + (public_name rinha) (name main) (flags (:standard -cclib -static -cclib -no-pie)) (libraries - rinhadebackend + rinha piaf routes diff --git a/bin/main.ml b/bin/main.ml index 7bf6048..7e537a7 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -1 +1,26 @@ -let () = print_endline "Hello, World!" +[@@@warning "-26-27-32"] + +open! StdLabels +open Eio +open Piaf + +let request_handler Server.{ request; _ } = + match Rinha.Router.match_route request.meth request.target with + | Some handler -> handler request + | None -> Response.create `Not_found +;; + +let () = + Eio_main.run + @@ fun env -> + Switch.run + @@ fun sw -> + let config = + let interface = Net.Ipaddr.V4.any in + let port = 3000 in + `Tcp (interface, port) + in + let config = Server.Config.create config in + let server = Server.create ~config request_handler in + ignore @@ Server.Command.start ~sw env server +;; diff --git a/docker-compose.yml b/docker-compose.yml index 28897d0..03ed942 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' services: api01: &api - image: rinhadebackend:latest + image: rinha:latest environment: - DB_HOST=db ports: diff --git a/dune-project b/dune-project index 2e174ca..1170cb9 100644 --- a/dune-project +++ b/dune-project @@ -1,6 +1,6 @@ (lang dune 3.13) -(name rinhadebackend) +(name rinha) (generate_opam_files true) @@ -16,7 +16,7 @@ (documentation https://url/to/documentation) (package - (name rinhadebackend) + (name rinha) (synopsis "A short synopsis") (description "A longer description") (depends ocaml dune) diff --git a/flake.nix b/flake.nix index 83eb5a3..f4b7ceb 100644 --- a/flake.nix +++ b/flake.nix @@ -20,8 +20,8 @@ pkgs' = pkgs.pkgsCross.musl64; - rinhadebackend = pkgs'.ocamlPackages.buildDunePackage { - pname = "rinhadebackend"; + rinha = pkgs'.ocamlPackages.buildDunePackage { + pname = "rinha"; version = "0.0.1"; src = ./.; buildInputs = with pkgs'.ocamlPackages; [ @@ -48,21 +48,21 @@ ocamlformat ]; - buildInputs = rinhadebackend.buildInputs + buildInputs = rinha.buildInputs ++ (with pkgs'.ocamlPackages; [ utop ]); }; - packages.default = rinhadebackend; + packages.default = rinha; - packages.docker = pkgs'.dockerTools.buildImage { - name = "ghcr.io/molvrr/rinhadebackend"; + packages.docker = pkgs.dockerTools.buildImage { + name = "rinha"; tag = "latest"; - copyToRoot = pkgs'.buildEnv { + copyToRoot = pkgs.buildEnv { name = "image-root"; - paths = [ pkgs'.bashInteractive pkgs'.coreutils pkgs'.curl rinhadebackend ]; + paths = [ pkgs.bashInteractive pkgs.coreutils pkgs.curl rinha ]; pathsToLink = [ "/bin" ]; }; - config = { Cmd = [ "rinhadebackend" ]; }; + config = { Cmd = [ "rinha" ]; }; }; formatter = pkgs.nixfmt; diff --git a/lib/dune b/lib/dune index 45a8131..837c7b7 100644 --- a/lib/dune +++ b/lib/dune @@ -1,2 +1,3 @@ (library - (name rinhadebackend)) + (name rinha) + (libraries piaf routes yojson)) diff --git a/lib/router.ml b/lib/router.ml new file mode 100644 index 0000000..cbff9fb --- /dev/null +++ b/lib/router.ml @@ -0,0 +1,59 @@ +[@@@warning "-26-27-32"] + +open StdLabels +open Routes +open Piaf + +module R = Map.Make (struct + type t = Method.t + + let compare a b = + let a_str = Method.to_string a in + let b_str = Method.to_string b in + String.compare a_str b_str + ;; + end) + +let transactions_route = + let handler client_id (request : Request.t) = + let json : Yojson.Safe.t = `Assoc [ "limite", `Int 100000; "saldo", `Int (-9098) ] in + Response.of_string ~body:(Yojson.Safe.to_string json) `OK + in + (s "clientes" / int / s "transacoes" /? nil) @--> handler +;; + +let balance_route = + let handler client_id (request : Request.t) = + let json : Yojson.Safe.t = + let balance = + let total = `Int (-9098) in + let date = `String "2024-01-17T02:34:41.217753Z" in + let limit = `Int 100000 in + `Assoc [ "total", total; "data_extrato", date; "limite", limit ] + in + let last_transactions = `List [] in + `Assoc [ "saldo", balance; "ultimas_transacoes", last_transactions ] + in + Response.of_string ~body:(Yojson.Safe.to_string json) `OK + in + (s "clientes" / int / s "extrato" /? nil) @--> handler +;; + +let routes = + List.fold_left + ~f:(fun acc (v, r) -> R.add_to_list v r acc) + [ `GET, balance_route; `POST, transactions_route; `POST, balance_route ] + ~init:R.empty +;; + +let router = R.map one_of routes + +let match_route verb path = + match R.find_opt verb router with + | Some router -> + (match match' router ~target:path with + | FullMatch r -> Some r + | MatchWithTrailingSlash r -> Some r + | NoMatch -> None) + | None -> None +;; diff --git a/lib/router.mli b/lib/router.mli new file mode 100644 index 0000000..c0b5915 --- /dev/null +++ b/lib/router.mli @@ -0,0 +1 @@ +val match_route : Piaf.Method.t -> string -> (Piaf.Request.t -> Piaf.Response.t) option diff --git a/rinha.opam b/rinha.opam new file mode 100644 index 0000000..3b957d2 --- /dev/null +++ b/rinha.opam @@ -0,0 +1,31 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "A short synopsis" +description: "A longer description" +maintainer: ["Maintainer Name"] +authors: ["Author Name"] +license: "LICENSE" +tags: ["topics" "to describe" "your" "project"] +homepage: "https://github.com/username/reponame" +doc: "https://url/to/documentation" +bug-reports: "https://github.com/username/reponame/issues" +depends: [ + "ocaml" + "dune" {>= "3.13"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/username/reponame.git" diff --git a/rinhadebackend.opam b/rinhadebackend.opam deleted file mode 100644 index 3b957d2..0000000 --- a/rinhadebackend.opam +++ /dev/null @@ -1,31 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -synopsis: "A short synopsis" -description: "A longer description" -maintainer: ["Maintainer Name"] -authors: ["Author Name"] -license: "LICENSE" -tags: ["topics" "to describe" "your" "project"] -homepage: "https://github.com/username/reponame" -doc: "https://url/to/documentation" -bug-reports: "https://github.com/username/reponame/issues" -depends: [ - "ocaml" - "dune" {>= "3.13"} - "odoc" {with-doc} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] -dev-repo: "git+https://github.com/username/reponame.git" diff --git a/test/dune b/test/dune index 9c10282..df3754d 100644 --- a/test/dune +++ b/test/dune @@ -1,2 +1,2 @@ (test - (name test_rinhadebackend)) + (name test_rinha)) diff --git a/test/test_rinha.ml b/test/test_rinha.ml new file mode 100644 index 0000000..e69de29 diff --git a/test/test_rinhadebackend.ml b/test/test_rinhadebackend.ml deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3