[ANN] Zero-cost fetch bindings - @glennsl/rescript-fetch

With ReScript v10 now out, it seems a good time to announce the release of @glennsl/rescript-fetch, the first (announced) library to take advantage of the new @optional feature, enabling fetch bindings that are both zero-cost and more ergonomic than previous iterations.

Here’s a taste:

let _: Promise.t<Js.Json.t> = {
  open Fetch

  let formData = FormData.make()
  formData->FormData.append(
    "image0",
    #Object({"type": "image/jpg", "uri": "path/to/it", "name": "image0.jpg"}),
  )

  fetch(
    "/api/upload",
    {
      method: #POST,
      body: Body.formData(formData),
      headers: Headers.fromObject({"Accept": "*"}),
    },
  )->Promise.then(Response.json)
}

Which compiles to:

var formData = new FormData();

formData.append("image0", {
      type: "image/jpg",
      uri: "path/to/it",
      name: "image0.jpg"
    });

fetch("/api/upload", {
        method: "POST",
        body: Caml_option.some(formData),
        headers: Caml_option.some(new Headers({
                  Accept: "*"
                }))
      }).then(function (prim) {
      return prim.json();
    });

These bindings should still be considered experimental and prone to breaking changes, however. But with a few more adventurous users we’ll hopefully sort any remaining issues out and have a stable 1.0 release in not too long.

15 Likes

Ah. I wasn’t sure if you’d be updating bs-fetch so we incorporated it into rescript-webapi last year :sweat_smile:

Apologies, I should’ve reached out first.

I’m planning to do an API update of webapi to make use of optional objects but haven’t had time to do much about that recently. That will be a good time to evaluate whether we should just link to the new rescript-fetch.

2 Likes

No worries. It’s not very obvious where some of these types should live. I’ve added bindings to FormData, for example, but Blob is just an abstract type. But with this having no code of its own, it might make more sense to depend on it and alias its types.

I never actually intended bs-fetch to be used directly. It was just supposed to be a minimal set of type-safe low-level bindings that you could use to build higher-level bindings. And I imagined there’d be several different experimental APIs battling out. I’m not aware of any outside my own attempt with re:fetch though.

So for these bindings I have strayed a bit further from the Fetch standard since I think these are actually quite ergonomic in themselves now, as opposed to the original bs-fetch.

1 Like