ReScript Node GraphQL Server?

I know this topic has come up from time to time and there might be a example repo out there, but curious if there is anything “real” or recent in the space that shows actual promise for using ReScript on the backend.

We recently started down the typescript road for the node server on a new project and we are REALLY missing ReScript.

Wanted to see if anyone is building real world projects with ReScript on the backend with Node.

3 Likes

There is https://github.com/sikanhe/reason-graphql

3 Likes

I have actually seen this repo in the past, I guess I am looking to hear if anyone is actually using this in production and what their experience has been, how limited they are, how hard is the binding management, etc

We’re using postgraphile with rescript, it works quite well for us so far.

2 Likes

I suspect the world of people willing to use rescript/ocaml on top of node on the backend has slightly more people using jsoo than rescript. I remember seeing some people mentioning using jsoo with node in discuss.ocaml.org, in the middle of other discussion threads, such as the dark lang post mortem.

2 Likes

From my side we have been using hasura for our graphql backend, and using rescript with nodejs for the hasura-actions (using serbet, but rescript-express or bs-express similar would be the same I guess). I also use rescript-apollo-client server-side when those actions need to interact with another graphql service.

Here is some example code (not very pollished, but will give you an idea at least), we have used the the same pattern on a number of production consulting projects (that are all closed source unfortunately).

I hope that could be useful for you when considering how to build your backend :slight_smile:

Dream looks cool

type user = {id : int; name : string}

let hardcoded_users = [
  {id = 1; name = "alice"};
  {id = 2; name = "bob"};
]

let user =
  Graphql_lwt.Schema.(obj "user"
    ~fields:(fun _info -> [
      field "id"
        ~typ:(non_null int)
        ~args:Arg.[]
        ~resolve:(fun _info user -> user.id);
      field "name"
        ~typ:(non_null string)
        ~args:Arg.[]
        ~resolve:(fun _info user -> user.name);
    ]))

let schema =
  Graphql_lwt.Schema.(schema [
    field "users"
      ~typ:(non_null (list (non_null user)))
      ~args:Arg.[arg "id" ~typ:int]
      ~resolve:(fun _info () id ->
        match id with
        | None -> hardcoded_users
        | Some id' ->
          match List.find_opt (fun {id; _} -> id = id') hardcoded_users with
          | None -> []
          | Some user -> [user]);
  ])

let () =
  Dream.run
  @@ Dream.logger
  @@ Dream.origin_referer_check
  @@ Dream.router [
    Dream.any "/graphql"  (Dream.graphql Lwt.return schema);
    Dream.get "/graphiql" (Dream.graphiql "/graphql");
  ]
  @@ Dream.not_found
3 Likes

Dream is very cool. It is using https://github.com/andreas/ocaml-graphql-server , which is a GraphQL server library. The significant thing about OCaml-GraphQL-Server is that it constrains the type of the resolvers based on the types of the schema, so it is checked at compile time.

1 Like

I am using ReScript (strictly speaking ReasonML as I haven’t made the conversion yet) + Apollo Server with Nodejs. Is there any particular reason this doesn’t work for you? Everything from the resolver and down is ReScript code.

ReScript + genType will export functions and values with Typescript types derived from the ReScript types that you can import and use in your Typescript files.

2 Likes