Code-first GraphQL schema generation on backend? (like NexusJS)

  1. Does anyone have experience with using ReScript to perform code-first GraphQL schema generation on the back-end?

I’m thinking about something like what Nexus does. Which leads me to ask:

  1. Does anyone have experience combining ReScript with Nexus? I’m not sure it would be less overhead (bindings and all included) than simply generating the schema based on the ReScript types.

Only article I’ve found is:

But it didn’t make me much wiser.

if you want to stick to JS backend, you could update https://github.com/sikanhe/reason-graphql to rescript likely without any blocker.

There are also a few options for an OCaml backend if you’re OK with this route.

1 Like

Yes, definitively check out that. There’s even a branch with work on upgrading it to ReScript: https://github.com/sikanhe/reason-graphql/pull/47

3 Likes

I’m a bit wary towards using a custom and unmaintained GraphQL server that I would also have to maintain going forward. I’d rather want to use an off-the-shelf GraphQL server (like Apollo Server Micro, or ideally Mercurius, with Relay support), and add some bindings if need be.

Writing bindings for complex and dynamic types can be quite hard too, especially since we’re still missing support for tagged templates in rescript and bindings can break if the underlying types change so the trade off is not always that obvious.

Binding to the official GraphQL.js (and graphql-tools) may suffice if you prefer the code-first approach. (I don’t think binding is the right approach if you want a fully integrated framework)

But you’ll still need a code generator or PPX to get an ergonomic DSL.

Nexus.js and Prisma provide plugins to handle these cases, so emitting ReScript modules based on it is better than binding by hand.

2 Likes

An actual Prisma generator for ReScript would be really great for adoption.

6 Likes

But you’ll still need a code generator or PPX to get an ergonomic DSL.

Why would you need a code generator if the goal is not to generate code but graphql schema?

Couldn’t it be done by annotating the types in ReScript, and then using those annotations as a basis for the GraphQL schema?

In general I’m not that much fan of code-generation, since it’s better (less complex) to target and output a more static non-turing-complete language (GraphQL), than a very dynamic and turing-complete one (ReScript). (cf. WC3’s Rule of Least Power)

What I wanted to mention is

  • Extending a GraphQL schema in different ways is common and the use case is not fixed.
  • Every single argument to a GraphQL resolver implicitly contains assumptions about polymorphism. This is good for duck typing languages, but languages like ReScript (or any languages wanna type-safety) need significantly more lines of code users to have to write by hand.
  • Maybe It’s enough for a codebase written from scratch in ReScript, but not if you are writing bindings to frameworks that already exist.
4 Likes

“Maybe It’s enough” → What does “it” refer to here?

I wish that reason-graphql (likely called rescript-graphql going forward) was not a server, but more a tool, such as Nexus. Since it gives more flexibility in choice of server, and lessens the requirements to the library. Nexus pits the benefit as: “The generated schema works with your favorite tools like Apollo Server or GraphQL middleware.” What do you think about that @sikan ?

That sounds like something that should be fairly trivial to fix though, taking the actual GraphQL execution and plugging it into another server.

Edit: It would also be interesting to see benchmarks of this vs something based on graphql-js. I think graphql-js is very optimized, so it’d be interesting to see how large the difference is.

1 Like

Just happened to come across this word of encouragement from @sgrove :

So for me the dream is being able to access all of these real-world API’s with all the type safety all the convenience that we saw from this not having to go through the JSON boilerplate and and the the dangerous runtime implications. This is huge. This is very similar for me when I was working with ClojureScript and David Nolan said that you know for him, even though he was the maintainer of it, it was basically a fun project, it was interesting, but until React came along it wasn’t real, because as soon as you touched the mutable DOM API all of your beautiful functional programming went to hell. Right? And react actually enabled us to have that functional interface with the DOM so that we could have all of the beautiful things like om, and suddenly there was a new domain opened up for ClojureScript that allowed it to be way way more efficient and way more effective and actually building real products. And so for Reason I think GraphQL is a very similar thing. So I would encourage all of you to go build GraphQL API’s for your services, so that we can enjoy them as Reason developers.

He is speaking about ocaml-graphql-server which turned into reason-graphql.

Personally, something like reason-graphql would be just great to have mature and properly set up for ReScript. I’d be all over that.

I guess the worry with something not based off of graphql-js is that you’d need to maintain and implement the same feature set, which might or might not be easy. Like @defer/@stream - two features I don’t think have made it into ocaml-graphql-server yet because they’re quite tricky to get right.

This is an interesting subject. To be honest, I really don’t mind codegen if it means that the resulting fw solves my problems in a good way. I wonder if one could have something with the ease of development of reason-graphql/ocaml-graphql-server, but that “compiles”/codegens into something that uses graphql-js under the hood. That would allow the fw to focus solely on the DX of building a (complicated) GraphQL schema in a safe and efficient way, and then rely on the mature ecosystem of graphql-js for the actual execution.

1 Like

Indeed. NexusJS is simply a layer on top of graphql-js.

As a sidenote, imagine what an opinionated full stack framework could do for adoption of ReScript… The market demand certainly seems to be there:

https://news.ycombinator.com/item?id=30206989&p=2

Imagine a full stack framework that integrated:

  • React (Native Web) on frontend.
  • NextJS for SSR and app structure. [1]
  • rescript-relay for GraphQL client.
  • rescript-graphql as a no-boilerplate code-first type & resolver layer on top of graphql-js with Mercurius+Fastify as the GraphQL server.

:drooling_face: It would mean you could get ReScript end-to-end type inference, with a fast and no-boilerplate GraphQL API. A full stack framework similar to RedwoodJS, but with SSR.

[1] Alternatively ViteJS with vite-plugin-ssr for the fastest bundling and flexible SSR (Maybe the upcoming VikeJS that uses these to compete with NextJS).

3 Likes

With regards to [1] and the frontend side, I’m working on something for SSR and rescript-relay, based on Vite. Not ready to show it just yet, but I’m hoping it’ll be a good alternative for a solid, production ready setup including SSR. Quite excited about it, looking forward to showing it once it’s ready.

6 Likes

Sounds interesting. How did you fare with rescript-relay and SSR on Vite?

Btw: vite-plugin-ssr renamed to Vike, and lists integration with Relay as one of it’s chief aims and advantages compared to NextJS : Relay (GraphQL) | Vike

1 Like

It needs some polish, and I still don’t personally need SSR so I’m hoping someone will contribute some polish at some point.

As for the original question, I’ve built ResGraph, an implementation/code first server GraphQL framework with a fairly novel approach: GitHub - zth/resgraph: Build implementation-first GraphQL servers in ReScript

4 Likes

I’m currently working on a template to use this with ReScript. If all goes well I would like to create a generator of some sorts with it.

Edit: the more i think about it the more i like this idea.

Vite SSR/SSG with Vike, rescript-relay, and resgraph give us a great full stack, batteries included structured app for ReScript that really let’s the language shine with its type system.

I’d probably add Jotai for state management, a css processor, and maybe an option or easy guide to add tailwind.

2 Likes