Reason and GraphQL

Reason and GraphQL

Using Reason's type inference we can create GraphQL servers with 100% type coverage. Regardless if we compile to Node.js or native binaries using Reason we can do this with ease.

Besides that Reason shines even more so on the client. Send one quick introspection request and you get full auto completion on your schema right in the browser.

Afcee4ad6e383e26799ff05681d1a2a5?s=128

Nikolaus Graf

October 19, 2018
Tweet

Transcript

  1. 1.
  2. 2.
  3. 10.
  4. 11.

    Benefits • The type of a field agrees with the

    return type of the resolve function. • The arguments of a field agrees with the accepted arguments of the resolve function. • The source of a field agrees with the type of the object to which it belongs. • The context argument for all resolver functions in a schema agree.
  5. 13.
  6. 14.
  7. 15.
  8. 16.
  9. 17.

    yarn add reason-apollo # Add graphql_ppx yarn add --dev graphql_ppx

    # Add JS dependencies yarn add react-apollo apollo-client graphql … "bs-dependencies": [ "reason-react", "reason-apollo" ], "ppx-flags": [ "graphql_ppx/ppx" ] yarn send-introspection-query http://localhost:8080/graphql
  10. 18.

    { "data": { "__schema": { "queryType": { "name": "query" },

    "mutationType": null, "subscriptionType": { "name": "subscription" }, "types": [ { "kind": "OBJECT", "name": "subscription", "description": null, "fields": [ { graphql_schema.json
  11. 19.

    let inMemoryCache = ApolloInMemoryCache.createInMemoryCache(); let httpLink = ApolloLinks.createHttpLink(~uri="/api/graphql", ()); let

    instance = ReasonApollo.createApolloClient( ~link=httpLink, ~cache=inMemoryCache, () ); Instantiate a Apollo Client
  12. 21.
  13. 22.
  14. 23.
  15. 24.
  16. 25.

    module GetUsers = [%graphql {| query users { users {

    id name } } |} ]; module GetUsersQuery = ReasonApollo.CreateQuery(GetUsers);
  17. 26.
  18. 27.
  19. 28.
  20. 29.
  21. 30.
  22. 31.
  23. 32.

    Let’s do it in TypeScript 1. Unique names for all

    your queries and mutation … (per directory?) 2. Download the schema
 apollo schema:download —endpoint=http://example.com graphql-schema.json 3. Generate the types
 apollo codegen:generate genTypes --schema=graphql-schema.json — queries=‘packages/**/src/**/*.ts*’ --passthroughCustomScalars -- customScalarsPrefix=GraphQl --addTypename --globalTypesFile=./packages/ types/src/global-graphql.ts 4. Import the Type and extend the Component
  24. 33.

    import { UsersQuery } from "./genTypes/UsersQuery"; const USERS_QUERY = gql`

    query UsersQuery { users { id name } } `; export default () => ( <Query<UsersQuery> query={USERS_QUERY}> {({ loading, error, data }) => { if (loading) return <div>Loading…</div>; if (error) return <div>Error</div>; if (!data) return null; // NOTE guarding that data is not null <ul> {data.users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul>; }} </Query> );
  25. 34.

    import { UsersQuery } from "./genTypes/UsersQuery"; const USERS_QUERY = gql`

    query UsersQuery { users { id name } } `; export default () => ( <Query<UsersQuery> query={USERS_QUERY}> {({ loading, error, data }) => { if (loading) return <div>Loading…</div>; if (error) return <div>Error</div>; if (!data) return null; // NOTE guarding that data is not null <ul> {data.users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul>; }} </Query> );
  26. 35.

    import { UsersQuery } from "./genTypes/UsersQuery"; const USERS_QUERY = gql`

    query UsersQuery { users { id name } } `; export default () => ( <Query<UsersQuery> query={USERS_QUERY}> {({ loading, error, data }) => { if (loading) return <div>Loading…</div>; if (error) return <div>Error</div>; if (!data) return null; // NOTE guarding that data is not null <ul> {data.users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul>; }} </Query> );
  27. 39.

    Things I like to see • Records instead of objects

    • Lists instead of Js.Array • Correct auto-completion inside the GraphQL PPX • Formatting of PPX
  28. 46.