diff --git a/esy.json b/esy.json index 0f85c2d..4216c68 100644 --- a/esy.json +++ b/esy.json @@ -1,10 +1,10 @@ { "name": "fetch", "version": "0.1.0", - "description": "A fetch library for ReasonML/OCaml", + "description": "Fetch libraries and interface for ReasonML/OCaml", "license": "MIT", "esy": { - "build": "dune build -p fetch-core", + "build": ["dune build -p fetch-core", "dune build -p fetch-native-lwt"], "buildDev": "refmterr dune build @all" }, "scripts": { diff --git a/esy.lock/index.json b/esy.lock/index.json index 3c00e0c..829bedd 100644 --- a/esy.lock/index.json +++ b/esy.lock/index.json @@ -59,14 +59,14 @@ "source": { "type": "link-dev", "path": ".", "manifest": "esy.json" }, "overrides": [], "dependencies": [ - "refmterr@3.2.2@d41d8cd9", "ocaml@4.7.1004@d41d8cd9", - "@reason-native/console@0.1.0@d41d8cd9", + "ocaml@4.7.1004@d41d8cd9", "@reason-native-web/morph_client@0.1.1@d41d8cd9", "@opam/reason@opam:3.5.0@40205ac4", "@opam/opium_core@github:rgrinberg/opium:opium_core.opam#287b83f85bcf6c75d503b1edab77c7ec524f9090@d41d8cd9", "@opam/dune@opam:1.11.3@9894df55" ], "devDependencies": [ + "refmterr@3.2.2@d41d8cd9", "@reason-native/console@0.1.0@d41d8cd9", "@opam/utop@opam:2.4.2@1cef5c4e", "@opam/rtop@opam:3.5.0@810d71c8", "@opam/merlin@opam:3.3.2@7a364181", "@opam/js_of_ocaml-compiler@opam:3.4.0@d2f7c406", diff --git a/examples/fetch_native_lwt_get.re b/examples/fetch_native_lwt_get.re index bbad4c4..389a35c 100644 --- a/examples/fetch_native_lwt_get.re +++ b/examples/fetch_native_lwt_get.re @@ -1,16 +1,18 @@ -open Fetch_native_lwt; +module Fetch = Fetch_native_lwt; -fetch("https://httpbin.org/get", ()) -|> Lwt.map( - fun - | Ok({Response.body, status, url, _}) => { - Printf.printf( - "Status-Code: %d\nBody: %s\nUrl: %s", - Response.Status.toCode(status), - Response.Body.toString(body), - url, - ); - } - | Error(_) => Printf.printf("That's an error"), - ) -|> Lwt_main.run; +Fetch.( + fetch("https://httpbin.org/get", ()) + |> Lwt.map( + fun + | Ok({Response.body, status, url, _}) => { + Printf.printf( + "Status-Code: %d\nBody: %s\nUrl: %s", + Response.Status.toCode(status), + Response.Body.toString(body), + url, + ); + } + | Error(_) => Printf.printf("That's an error"), + ) + |> Lwt_main.run +); diff --git a/fetch-core.json b/fetch-core.json new file mode 100644 index 0000000..782826c --- /dev/null +++ b/fetch-core.json @@ -0,0 +1,27 @@ +{ + "name": "fetch-core", + "version": "0.1.0", + "description": "A fetch interface/functor for ReasonML/OCaml", + "license": "MIT", + "esy": { + "build": "dune build --profile=release ./src/fetch-core", + "buildDev": "refmterr dune build @all" + }, + "scripts": { + "format": "esy dune build @fmt --auto-promote", + "test": "esy dune runtest test" + }, + "dependencies": { + "@opam/dune": "^1.11.1", + "@opam/reason": "^3.5.0", + "ocaml": "<4.8.0" + }, + "devDependencies": { + "refmterr": "^3.2.2", + "@opam/alcotest": "0.8.5", + "@opam/js_of_ocaml-compiler": "3.4.0", + "@opam/merlin": "^3.3.2", + "@opam/rtop": "3.5.0", + "@opam/utop": "2.4.2" + } +} diff --git a/fetch-native-lwt.json b/fetch-native-lwt.json new file mode 100644 index 0000000..73fe946 --- /dev/null +++ b/fetch-native-lwt.json @@ -0,0 +1,30 @@ +{ + "name": "fetch-native-lwt", + "version": "0.1.0", + "description": "Fetch client (Lwt) for native ReasonML/OCaml", + "license": "MIT", + "esy": { + "build": "dune build --profile=release ./src/fetch-native-lwt", + "buildDev": "refmterr dune build @all" + }, + "scripts": { + "format": "esy dune build @fmt --auto-promote" + }, + "dependencies": { + "@opam/dune": "^1.11.1", + "@opam/reason": "^3.5.0", + "@reason-native-web/morph_client": "^0.1.1", + "ocaml": "<4.8.0" + }, + "devDependencies": { + "refmterr": "^3.2.2", + "@opam/merlin": "^3.3.2", + "@opam/rtop": "3.5.0", + "@opam/utop": "2.4.2" + }, + "resolutions": { + "@opam/httpaf-lwt-unix": "anmonteiro/httpaf:httpaf-lwt-unix.opam#76b461bed081c64908fb1fdfa076ab2c936ca622", + "@opam/httpaf-lwt": "anmonteiro/httpaf:httpaf-lwt.opam#76b461bed081c64908fb1fdfa076ab2c936ca622", + "@opam/httpaf": "anmonteiro/httpaf:httpaf.opam#76b461bed081c64908fb1fdfa076ab2c936ca622" + } +} diff --git a/src/fetch-core/README.md b/src/fetch-core/README.md new file mode 100644 index 0000000..2d0d4c4 --- /dev/null +++ b/src/fetch-core/README.md @@ -0,0 +1,39 @@ +# Fetch + +A fetch interface/functor for ReasonML/OCaml. + +# Table of Contents + +- [What](#what) +- [Why](#why) + +## What? + +Fetch aims to provide a common interface over different HTTP and Promise-implementations in the ReasonML/OCaml ecosystem. + +It is based on the Fetch-specification from [Whatwg](https://fetch.spec.whatwg.org/), but makes conscious trade-offs. It has also taken inspiration and attempted to follow community-idioms and best practices with regards to HTTP-requests. + +The goal is to be pluggable with any HTTP or Promise-implementation provided it conforms to the common interface. + +E.g. + +```re +module Fetch = Fetch_core.Fetchify.Make({ + module Response = { + /* your implementation */ + }; + + type t = Promise.t(result(Response.t, exn)); + + let make = (req: Request.t) => /* your custom implementation */ +}); +``` + +## Why? + +There are several different implementations for making HTTP-requests and for handling asynchronous code in the ReasonML/OCaml ecosystem. +This is ultimately a good thing as helps in improving the ecosystem, and also, most times there isn't always a one-size fits all. + +The goal is to reduce the burden of transitioning between as well as picking a library to begin with. + +By making the implementation-details agnostic and trying to specify a common interface which is also a bit higher-level it hopefully strikes a good balance and can be useful for the community as a whole. diff --git a/fetch-core/body.rei b/src/fetch-core/body.rei similarity index 100% rename from fetch-core/body.rei rename to src/fetch-core/body.rei diff --git a/fetch-core/dune b/src/fetch-core/dune similarity index 100% rename from fetch-core/dune rename to src/fetch-core/dune diff --git a/fetch-core/fetch_core.re b/src/fetch-core/fetch_core.re similarity index 100% rename from fetch-core/fetch_core.re rename to src/fetch-core/fetch_core.re diff --git a/fetch-core/fetch_core.rei b/src/fetch-core/fetch_core.rei similarity index 100% rename from fetch-core/fetch_core.rei rename to src/fetch-core/fetch_core.rei diff --git a/fetch-core/fetchify.re b/src/fetch-core/fetchify.re similarity index 100% rename from fetch-core/fetchify.re rename to src/fetch-core/fetchify.re diff --git a/fetch-core/fetchify.rei b/src/fetch-core/fetchify.rei similarity index 100% rename from fetch-core/fetchify.rei rename to src/fetch-core/fetchify.rei diff --git a/fetch-core/headers.re b/src/fetch-core/headers.re similarity index 100% rename from fetch-core/headers.re rename to src/fetch-core/headers.re diff --git a/fetch-core/headers.rei b/src/fetch-core/headers.rei similarity index 100% rename from fetch-core/headers.rei rename to src/fetch-core/headers.rei diff --git a/fetch-core/method.re b/src/fetch-core/method.re similarity index 100% rename from fetch-core/method.re rename to src/fetch-core/method.re diff --git a/fetch-core/method.rei b/src/fetch-core/method.rei similarity index 100% rename from fetch-core/method.rei rename to src/fetch-core/method.rei diff --git a/fetch-core/request.re b/src/fetch-core/request.re similarity index 100% rename from fetch-core/request.re rename to src/fetch-core/request.re diff --git a/fetch-core/request.rei b/src/fetch-core/request.rei similarity index 100% rename from fetch-core/request.rei rename to src/fetch-core/request.rei diff --git a/fetch-core/response.re b/src/fetch-core/response.re similarity index 100% rename from fetch-core/response.re rename to src/fetch-core/response.re diff --git a/fetch-core/response.rei b/src/fetch-core/response.rei similarity index 100% rename from fetch-core/response.rei rename to src/fetch-core/response.rei diff --git a/fetch-core/s.re b/src/fetch-core/s.re similarity index 100% rename from fetch-core/s.re rename to src/fetch-core/s.re diff --git a/fetch-core/status.re b/src/fetch-core/status.re similarity index 100% rename from fetch-core/status.re rename to src/fetch-core/status.re diff --git a/fetch-core/status.rei b/src/fetch-core/status.rei similarity index 100% rename from fetch-core/status.rei rename to src/fetch-core/status.rei diff --git a/src/fetch-native-lwt/README.md b/src/fetch-native-lwt/README.md new file mode 100644 index 0000000..cfe7465 --- /dev/null +++ b/src/fetch-native-lwt/README.md @@ -0,0 +1,38 @@ +# fetch-native-lwt + +Fetch client for native ReasonML. + +## Getting started + +1. Install + +```sh +esy add fetch-native-lwt +``` + +2. Add Fetch to your dune libraries: + +```lisp +(libraries ... fetch-native-lwt) +``` + +3. Make your first request: + +```re +open Fetch_native_lwt; + +fetch("https://httpbin.org/get", ()) +|> Lwt.map( + fun + | Ok({Response.body, status, url, _}) => { + Printf.printf( + "Status-Code: %d\nBody: %s\nUrl: %s", + Response.Status.toCode(status), + Response.Body.toString(body), + url, + ); + } + | Error(_) => Printf.printf("That's an error"), + ) +|> Lwt_main.run; +``` diff --git a/fetch-native-lwt/dune b/src/fetch-native-lwt/dune similarity index 100% rename from fetch-native-lwt/dune rename to src/fetch-native-lwt/dune diff --git a/fetch-native-lwt/fetch_native_lwt.re b/src/fetch-native-lwt/fetch_native_lwt.re similarity index 100% rename from fetch-native-lwt/fetch_native_lwt.re rename to src/fetch-native-lwt/fetch_native_lwt.re