Git Product home page Git Product logo

reason-graphql-fullstack's Introduction

Reason / GraphQL Shared Backend

This is an example of a fullstack Reason + GraphQL application that uses a native backend and a client compiled to JavaScript through BuckleScript, whilst sharing types between the backend and the frontend.

Technologies / Libraries:

This was initially based on @jaredly's isomagic-todos experiment that accomplished sharing types between the backend & frontend through some PPX magic.

In this case, we leverage the power of GraphQL and its support in OCaml through ocaml-graphql-server and graphql_ppx to build our API through shared OCaml / Reason types (have a look in src/shared).

Running

Build the front-end

  • yarn && yarn build && yarn bundle

Build and run the backend

Note: it's a quiet startup; check http://localhost:8080/graphql to see that it's running!

  • npm install -g esy
  • esy @server
  • esy @server x graphql

Neat tricks

  • GraphQL schema fully defined in Reason (see src/server/schema.re)
  • There's also a GraphiQL instance at localhost:8080/graphql for exploring and playing with the queries and mutations.

License

MIT

reason-graphql-fullstack's People

Contributors

anmonteiro avatar dvisztempacct avatar naartjie avatar thatportugueseguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reason-graphql-fullstack's Issues

Suggestions

Thanks for sharing your code, @anmonteiro! πŸ™It's great to have some more examples out there.

Two quick suggestions/questions:

  • Could some of the usages of io_field be replaced with field to avoid Lwt_result.return, e.g. this one?
  • Could you use use HTTP server that ships with graphql-lwt, or does it lack some feature compared to the one you implemented? At a glance they seem quite similar.

Client - server port issue

Trivial question: (BTW, very nice project, this helps me a lot)

I see the the sample client tries to connect to http://localhost/public which is not where the server is located.

I tried changing the line in Loader.re to:

let sendQuery = q =>
  Bs_fetch.(
    fetchWithInit(
      "http://localhost:8080/graphql",
      RequestInit.make(

But my newbie knowledge of Bs_fetch is obviously flawed. Fidder reports that this is what is being sent:

OPTIONS http://localhost:8080/graphql HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://127.0.0.1:5500
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Referer: http://127.0.0.1:5500/public/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,he;q=0.8,yi;q=0.7

Suggestions + Questions

Thank you for your example!

Suggestions

  • It would be nice if you add some explanation about the steps you took to set up this project and why.
  • I'm new to Reason would appreciate some comment about the choices you've made and what other alternatives you've considered.

Questions

I was trying to set up a full stack Reason app. When I looked at your example everything happens in the first commit and it's difficult for me to see the steps. I was wondering if this is roughly what you did to set up this project?

  1. initialize a ReasonReact app
    bsb -init my-react-app -theme react
  2. ignore the JS files created in the build process
    add *.bs.js to .gitignore file
  3. create client and shared sub-directory
    update the entry point of Webpack
    add the subdirs to the bsconfig file
  4. add reason-apollo
    Follow the install instructions in https://github.com/apollographql/reason-apollo
    • yarn add reason-apollo
    • yarn add --dev graphql_ppx
    • yarn add react-apollo apollo-client apollo-cache-inmemory apollo-link apollo-link-context apollo-link-error apollo-link-http graphql graphql-tag
    • Add reason-apollo to your bs-dependencies and graphql_ppx/ppx to your ppx_flags
  5. create a opam package
  6. add dune config
    dune-project, server/jbuild, shared/jbuild

Thoughts on database layer?

This project is very cool, but I'm wondering about your (or anyone's) thoughts on how to implement a persistence/database layer. It seems there is more effort around generating a GraphQL schema from a database (e.g., Postgraphile, Hasura) rather than the other way around, as seems to be required with the approach here. There's a discussion about this aspect of the problem graphile/crystal#592 here, but nothing particularly satisfying resulted. Maybe I'm just missing something and making this project persist the data is easier than it seems?

an expression was expected of type Shared.Types.todo list GQL.Schema.io = Shared.Types.todo list Lwt.t

Using opam 2.0.0~rc2 and ocamlc 4.06.1 trying to build reason-graphql-fullstack 85dd67be8f3f4ea663f0834e5ff280a24cea618b I had to manually install an extra package cohttp-lwt-unix 1.0.2 to get it to run ocamlc

donviszneki@Dons-MacBook-Pro ~/foobar$ jbuilder build @graphql && jbuilder exec graphql
File "/Users/donviszneki/.opam/default/lib/cohttp/META", line 1, characters 0-0:
Error: Library "cohttp-lwt-unix" not found.
-> required by library "cohttp.lwt" in /Users/donviszneki/.opam/default/lib/cohttp

Once that was solved, ocamlc gave me the following error:

donviszneki@Dons-MacBook-Pro ~/foobar$ jbuilder build @graphql && jbuilder exec graphql
      ocamlc src/server/.main.eobjs/schema.{cmi,cmo,cmt} (exit 2)
(cd _build/default && /usr/local/bin/ocamlc.opt -w -40 -g -bin-annot -I src/server/.main.eobjs -I /Users/donviszneki/.opam/default/lib/angstrom -I /Users/donviszneki/.opam/default/lib/astring -I /Users/donviszneki/.opam/default/lib/base -I /Users/donviszneki/.opam/default/lib/base/caml -I /Users/donviszneki/.opam/default/lib/base/shadow_stdlib -I /Users/donviszneki/.opam/default/lib/base64 -I /Users/donviszneki/.opam/default/lib/biniou -I /Users/donviszneki/.opam/default/lib/bytes -I /Users/donviszneki/.opam/default/lib/cohttp -I /Users/donviszneki/.opam/default/lib/cohttp-lwt -I /Users/donviszneki/.opam/default/lib/cohttp-lwt-unix -I /Users/donviszneki/.opam/default/lib/conduit -I /Users/donviszneki/.opam/default/lib/conduit-lwt -I /Users/donviszneki/.opam/default/lib/conduit-lwt-unix -I /Users/donviszneki/.opam/default/lib/easy-format -I /Users/donviszneki/.opam/default/lib/fieldslib -I /Users/donviszneki/.opam/default/lib/fmt -I /Users/donviszneki/.opam/default/lib/graphql -I /Users/donviszneki/.opam/default/lib/graphql-lwt -I /Users/donviszneki/.opam/default/lib/graphql_parser -I /Users/donviszneki/.opam/default/lib/ipaddr -I /Users/donviszneki/.opam/default/lib/ipaddr/unix -I /Users/donviszneki/.opam/default/lib/logs -I /Users/donviszneki/.opam/default/lib/lwt -I /Users/donviszneki/.opam/default/lib/magic-mime -I /Users/donviszneki/.opam/default/lib/parsexp -I /Users/donviszneki/.opam/default/lib/ppx_sexp_conv/runtime-lib -I /Users/donviszneki/.opam/default/lib/re -I /Users/donviszneki/.opam/default/lib/re/emacs -I /Users/donviszneki/.opam/default/lib/re/posix -I /Users/donviszneki/.opam/default/lib/result -I /Users/donviszneki/.opam/default/lib/rresult -I /Users/donviszneki/.opam/default/lib/sexplib -I /Users/donviszneki/.opam/default/lib/sexplib0 -I /Users/donviszneki/.opam/default/lib/stringext -I /Users/donviszneki/.opam/default/lib/uchar -I /Users/donviszneki/.opam/default/lib/uri -I /Users/donviszneki/.opam/default/lib/uri/services -I /Users/donviszneki/.opam/default/lib/yojson -I /usr/local/lib/ocaml/threads -I src/shared/.shared.objs -no-alias-deps -o src/server/.main.eobjs/schema.cmo -c -impl src/server/schema.re.ml)
File "src/server/schema.re", line 63, characters 12-59:
Error: This expression has type
         (Shared.Types.todo list, 'a) Lwt_result.t =
           (Shared.Types.todo list, 'a) Result.result Lwt.t
       but an expression was expected of type
         Shared.Types.todo list GQL.Schema.io = Shared.Types.todo list Lwt.t
       Type
         (Shared.Types.todo list, 'a) Result.result =
           (Shared.Types.todo list, 'a) Pervasives.result
       is not compatible with type Shared.Types.todo list
      ocamlc src/server/.main.eobjs/server.{cmi,cmo,cmt}
File "src/server/server.re", line 48, characters 6-40:
Warning 10: this expression should have type unit.
File "src/server/server.re", line 56, characters 6-41:
Warning 10: this expression should have type unit.
File "src/server/server.re", line 80, characters 2-42:
Warning 10: this expression should have type unit.
    ocamlopt src/server/.main.eobjs/server.{cmx,o}
File "src/server/server.re", line 48, characters 6-40:
Warning 10: this expression should have type unit.
File "src/server/server.re", line 56, characters 6-41:
Warning 10: this expression should have type unit.
File "src/server/server.re", line 80, characters 2-42:
Warning 10: this expression should have type unit.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.