SlideShare a Scribd company logo
with Reason
Incremental Type Safety
in React Apollo
Evans Hauser
Core Developer, Apollo
Apollo Project 🚀
import React from 'react';
import { render } from 'react-dom';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import App from ‘./App';
const client = new ApolloClient({
uri: ‘https://localhost:3010/graphql'
});
const ApolloApp = () => (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
render(ApolloApp, document.getElementById('root'));)
index.js
import FreeJobPost from “./FreeJobPost.js”

import PromotedPost from “./PromotedPost.js”
…
render() {
...
<FreeJobPost info={info1} />
<FreeJobPost info={info2} />
<FreeJobPost info={info3} />
<PromotedPost info={info4} />
...
}
App.js Adding to the 🚀
What about Reason 🤔
npm install bs-platform
npm install reason-react
{
"name": “package-name",
"sources": {
"dir": "src",
"subdirs": [“components"],
},
"reason": {
"react-jsx": 2
},
"refmt": 3
}
bsconfig.json
How to add Reason to your 🚀
Build: bsb -make-world
Watch: bsb -make-world -w
import PromotedPost from “./PromotedPost.bs.js”
render() {
...
<FreeJobPost info={info1} />
<FreeJobPost info={info2} />
<FreeJobPost info={info3} />
<PromotedPost info={info4} />
...
}
App.js Inside the 🚀
let component =
ReasonReact.statelessComponent(“PromotedPost”);
let make = (~info, _children) => {
...component,
render: (self) =>
<div>
<Post text=info.text timeLeft=info.timeLeft />
</div>
};
let default =
ReasonReact.wrapReasonForJs(
~component,
(props) => make(~info=settingsInfoFromJs(props##info), [||])
);
PromotedPost.re Adding Reason
PromotedPost.re Adding Reason
let component =
ReasonReact.statelessComponent(“PromotedPost”);
let make = (~info, _children) => {
...component,
render: (self) =>
<div>
<Post text=info.text timeLeft=info.timeLeft />
</div>
};
let default =
ReasonReact.wrapReasonForJs(
~component,
(props) => make(~info=settingsInfoFromJs(props##info), [||])
);
PromotedPost.re Adding Reason
let component =
ReasonReact.statelessComponent(“PromotedPost”);
let make = (~info, _children) => {
...component,
render: (self) =>
<div>
<Post text=info.text timeLeft=info.timeLeft />
</div>
};
let default =
ReasonReact.wrapReasonForJs(
~component,
(props) => make(~info=settingsInfoFromJs(props##info), [||])
);
let component =
ReasonReact.statelessComponent(“Post”);
let make = (~text, ~timeLeft, _children) => {
…component,
render: (self) =>
<input
_type=“checkbox”
value=text
checked=(text > 0)
/>
};
Post.re Reason Subcomponent
Reason FTW
Strong Typing 💪
let component =
ReasonReact.statelessComponent(“Post”);
let make = (~text, ~timeLeft, _children) => {
…component,
render: (self) =>
<input
_type=“checkbox”
value=text
checked=(timeLeft > 0)
/>
};
Post.re Reason Subcomponent
Pitfall
🎉 JS Interop 🎉
let component =
ReasonReact.statelessComponent(“Post”);
let make = (~text, ~timeLeft, _children) => {
…component,
render: (self) =>
<input
_type=“checkbox”
value=text
checked=(Js.Boolean.to_js_boolean(timeLeft > 0))
/>
};
Post.re Javascript Interop
PromotedPost.re Adding Reason
let component =
ReasonReact.statelessComponent(“PromotedPost”);
let make = (~info, _children) => {
...component,
render: (self) =>
<div>
<Post text=info.text timeLeft=info.timeLeft />
</div>
};
let default =
ReasonReact.wrapReasonForJs(
~component,
(props) => make(~info=settingsInfoFromJs(props##info), [||])
);
PromotedPost.re More Interop
let component =
ReasonReact.statelessComponent(“PromotedPost”);
let make = (~info, _children) => {
...component,
render: (self) =>
<div>
<p>Promoted Posting:</p>
<Post text=info.text timeLeft=info.timeLeft />
</div>
};
let default =
ReasonReact.wrapReasonForJs(
~component,
(props) => make(~info=settingsInfoFromJs(props##info), [||])
);
type postInfo = {.
“text”: string,
“timeLeft”: number
};
let postInfoFromJs = (jsInfo : postInfo) => {
text: jsInfo##text,
timeLeft: jsInfo##timeLeft
};
const examplePosting = {
“text”: “description of posting”,
“timeLeft”: 200
};
Defining TypesPromotedPost.re
App.js
What about GraphQL 🤔
Typed Query Language
Strong Reason support
Creating separation through GraphQL
npm install graphql_ppx
npm install reason_apollo
{
"bs-dependencies": [
"reason-react",
“reason-apollo"
],
"ppx-flags": [
"./node_modules/graphql_ppx/ppx -ast-out"
],
}
bsconfig.json
Adding GraphQL to your 🚀
Separation through GraphQL
module PromotedPostQuery = [%graphql {|
query getPromotedPosts {
info {
text
timeLeft
}
}
|}];
let promotedPosts = PromotedPostQuery.make(());
GqlPost.re
Separation through GraphQL
let component = ReasonReact.statelessComponent("PromotedPost");
[@bs.module "react-apollo"] external gql: 'a =>
[@bs] ReasonReact.reactClass => ReasonReact.reactClass = "graphql";
let wrap = (gql (promotedPosts##query));
let default =
[@bs] wrap (ReasonReact.wrapReasonForJs(
~component,
(props : {..
"data": {..
"data": TodosQuery.t,
"loading": Js.boolean,
}
}) => make(~result=props, [||])
)
));
GqlPost.re
Separation through GraphQL
let make = (~result, _children) => {
...component,
render: (self) =>
if(Js.to_bool (result##data##loading)){
<div> <String text="Loading"/> </div>
} else {
let text = result##data##info##text;
let timeLeft = result##data##info##timeLeft;
<div>
<Post text=text timeLeft=timeLeft />
</div>
}
};
GqlPost.re
A Possible API
module PromotedPostQuery = [%graphql {|
query getPromotedPosts {
info {
text
timeLeft
}
}
|}];
let make = (~result, _children) => {
...component,
render: (self) =>
if(Js.to_bool (result##loading)){
<div> <String text="Loading"/> </div>
} else {
let text = result##data##info##text;
let timeLeft = result##data##info##timeLeft;
<div>
<Post text=info.text timeLeft=info.timeLeft />
</div>
}
};
let default = ReasonApollo.graphql (PromotedPostsQuery) {"PromotedPost", make);
Let’s collaborate!
Evans Hauser
@evanshauser
evans@apollograpql.com
• Next Steps:
• Ensure that your types work
across the client server
boundary
• Manage client-side state with
apollo-link-state
Huge thank you to Ben Souci for his
help putting together this talk!

More Related Content

PPTX
Zero to SOLID
PDF
Improving apps with iOS 10 notifications (do iOS 2016)
PPTX
Python Code Camp for Professionals 2/4
PPTX
Gary Gao: APIs Are Good
PPTX
Python Code Camp for Professionals 1/4
PDF
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
PDF
OSCON Google App Engine Codelab - July 2010
PPTX
Build Lightweight Web Module
Zero to SOLID
Improving apps with iOS 10 notifications (do iOS 2016)
Python Code Camp for Professionals 2/4
Gary Gao: APIs Are Good
Python Code Camp for Professionals 1/4
Demystifying Hooks, Actions & Filters - WordCamp Belfast 2018
OSCON Google App Engine Codelab - July 2010
Build Lightweight Web Module

What's hot (20)

PDF
Getting Started-with-Laravel
PDF
Me and my importers
PDF
Phing101 or How to staff a build orchestra
PPTX
Python Code Camp for Professionals 3/4
PPTX
Python Code Camp for Professionals 4/4
PDF
Tips and tricks for building api heavy ruby on rails applications
KEY
JavaScript Testing for Rubyists
PDF
Silex Cheat Sheet
PDF
Rails 3 overview
PDF
Complex Sites with Silex
PPTX
Алексей Плеханов: Новинки Laravel 5
PDF
A Little Backbone For Your App
PDF
Crafting [Better] API Clients
PPTX
Dealing with Continuous Data Processing, ConFoo 2012
PPTX
21.search in laravel
PPTX
Quick Fetch API Introduction
PDF
JavaCro'15 - Remote controlling Parrot AR Drone with Spring Boot and Vaadin -...
PDF
How to develop modern web application framework
PPTX
Powershell function
PDF
優しいWAFの作り方
Getting Started-with-Laravel
Me and my importers
Phing101 or How to staff a build orchestra
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 4/4
Tips and tricks for building api heavy ruby on rails applications
JavaScript Testing for Rubyists
Silex Cheat Sheet
Rails 3 overview
Complex Sites with Silex
Алексей Плеханов: Новинки Laravel 5
A Little Backbone For Your App
Crafting [Better] API Clients
Dealing with Continuous Data Processing, ConFoo 2012
21.search in laravel
Quick Fetch API Introduction
JavaCro'15 - Remote controlling Parrot AR Drone with Spring Boot and Vaadin -...
How to develop modern web application framework
Powershell function
優しいWAFの作り方
Ad

Similar to Incremental Type Safety in React Apollo (20)

PDF
Apollo ecosystem
PDF
GraphQL Los Angeles Meetup Slides
PDF
Apollo. The client we deserve
PDF
React meets o OCalm
PDF
react-apollo
PDF
Lessons Learned Implementing a GraphQL API
PPTX
Create flexible React applications using GraphQL apis
PDF
Reason and GraphQL
PPTX
Create flexible react applications using GraphQL API's
PPTX
Create flexible React applications using GraphQL APIs - Maurice de Beijer - C...
PDF
Linux conf-2018-fp-miniconf-slideshare
PDF
Fly me to the moon
PDF
Using ReasonML For Your Next JavaScript Project
PDF
Getting started with Apollo Client and GraphQL
PDF
Diving into GraphQL, React & Apollo
PDF
Reason React
PPT
Graphql presentation
PDF
The Apollo and GraphQL Stack
PDF
Sashko Stubailo - The GraphQL and Apollo Stack: connecting everything together
PDF
NodeJS The edge of Reason - Lille fp#6
Apollo ecosystem
GraphQL Los Angeles Meetup Slides
Apollo. The client we deserve
React meets o OCalm
react-apollo
Lessons Learned Implementing a GraphQL API
Create flexible React applications using GraphQL apis
Reason and GraphQL
Create flexible react applications using GraphQL API's
Create flexible React applications using GraphQL APIs - Maurice de Beijer - C...
Linux conf-2018-fp-miniconf-slideshare
Fly me to the moon
Using ReasonML For Your Next JavaScript Project
Getting started with Apollo Client and GraphQL
Diving into GraphQL, React & Apollo
Reason React
Graphql presentation
The Apollo and GraphQL Stack
Sashko Stubailo - The GraphQL and Apollo Stack: connecting everything together
NodeJS The edge of Reason - Lille fp#6
Ad

Recently uploaded (20)

PPTX
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
PDF
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
DOCX
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
PDF
Embodied AI: Ushering in the Next Era of Intelligent Systems
PDF
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PPTX
Geodesy 1.pptx...............................................
PPT
Mechanical Engineering MATERIALS Selection
PPTX
additive manufacturing of ss316l using mig welding
PPT
CRASH COURSE IN ALTERNATIVE PLUMBING CLASS
PDF
TFEC-4-2020-Design-Guide-for-Timber-Roof-Trusses.pdf
PPT
Project quality management in manufacturing
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PPTX
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
PDF
R24 SURVEYING LAB MANUAL for civil enggi
PPTX
Sustainable Sites - Green Building Construction
PDF
PPT on Performance Review to get promotions
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PDF
composite construction of structures.pdf
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
UNIT-1 - COAL BASED THERMAL POWER PLANTS
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
Embodied AI: Ushering in the Next Era of Intelligent Systems
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
Geodesy 1.pptx...............................................
Mechanical Engineering MATERIALS Selection
additive manufacturing of ss316l using mig welding
CRASH COURSE IN ALTERNATIVE PLUMBING CLASS
TFEC-4-2020-Design-Guide-for-Timber-Roof-Trusses.pdf
Project quality management in manufacturing
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
R24 SURVEYING LAB MANUAL for civil enggi
Sustainable Sites - Green Building Construction
PPT on Performance Review to get promotions
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
composite construction of structures.pdf

Incremental Type Safety in React Apollo

  • 1. with Reason Incremental Type Safety in React Apollo Evans Hauser Core Developer, Apollo
  • 2. Apollo Project 🚀 import React from 'react'; import { render } from 'react-dom'; import ApolloClient from 'apollo-boost'; import { ApolloProvider } from 'react-apollo'; import App from ‘./App'; const client = new ApolloClient({ uri: ‘https://localhost:3010/graphql' }); const ApolloApp = () => ( <ApolloProvider client={client}> <App /> </ApolloProvider> ); render(ApolloApp, document.getElementById('root'));) index.js
  • 3. import FreeJobPost from “./FreeJobPost.js”
 import PromotedPost from “./PromotedPost.js” … render() { ... <FreeJobPost info={info1} /> <FreeJobPost info={info2} /> <FreeJobPost info={info3} /> <PromotedPost info={info4} /> ... } App.js Adding to the 🚀
  • 5. npm install bs-platform npm install reason-react { "name": “package-name", "sources": { "dir": "src", "subdirs": [“components"], }, "reason": { "react-jsx": 2 }, "refmt": 3 } bsconfig.json How to add Reason to your 🚀 Build: bsb -make-world Watch: bsb -make-world -w
  • 6. import PromotedPost from “./PromotedPost.bs.js” render() { ... <FreeJobPost info={info1} /> <FreeJobPost info={info2} /> <FreeJobPost info={info3} /> <PromotedPost info={info4} /> ... } App.js Inside the 🚀
  • 7. let component = ReasonReact.statelessComponent(“PromotedPost”); let make = (~info, _children) => { ...component, render: (self) => <div> <Post text=info.text timeLeft=info.timeLeft /> </div> }; let default = ReasonReact.wrapReasonForJs( ~component, (props) => make(~info=settingsInfoFromJs(props##info), [||]) ); PromotedPost.re Adding Reason
  • 8. PromotedPost.re Adding Reason let component = ReasonReact.statelessComponent(“PromotedPost”); let make = (~info, _children) => { ...component, render: (self) => <div> <Post text=info.text timeLeft=info.timeLeft /> </div> }; let default = ReasonReact.wrapReasonForJs( ~component, (props) => make(~info=settingsInfoFromJs(props##info), [||]) );
  • 9. PromotedPost.re Adding Reason let component = ReasonReact.statelessComponent(“PromotedPost”); let make = (~info, _children) => { ...component, render: (self) => <div> <Post text=info.text timeLeft=info.timeLeft /> </div> }; let default = ReasonReact.wrapReasonForJs( ~component, (props) => make(~info=settingsInfoFromJs(props##info), [||]) );
  • 10. let component = ReasonReact.statelessComponent(“Post”); let make = (~text, ~timeLeft, _children) => { …component, render: (self) => <input _type=“checkbox” value=text checked=(text > 0) /> }; Post.re Reason Subcomponent
  • 12. let component = ReasonReact.statelessComponent(“Post”); let make = (~text, ~timeLeft, _children) => { …component, render: (self) => <input _type=“checkbox” value=text checked=(timeLeft > 0) /> }; Post.re Reason Subcomponent
  • 14. let component = ReasonReact.statelessComponent(“Post”); let make = (~text, ~timeLeft, _children) => { …component, render: (self) => <input _type=“checkbox” value=text checked=(Js.Boolean.to_js_boolean(timeLeft > 0)) /> }; Post.re Javascript Interop
  • 15. PromotedPost.re Adding Reason let component = ReasonReact.statelessComponent(“PromotedPost”); let make = (~info, _children) => { ...component, render: (self) => <div> <Post text=info.text timeLeft=info.timeLeft /> </div> }; let default = ReasonReact.wrapReasonForJs( ~component, (props) => make(~info=settingsInfoFromJs(props##info), [||]) );
  • 16. PromotedPost.re More Interop let component = ReasonReact.statelessComponent(“PromotedPost”); let make = (~info, _children) => { ...component, render: (self) => <div> <p>Promoted Posting:</p> <Post text=info.text timeLeft=info.timeLeft /> </div> }; let default = ReasonReact.wrapReasonForJs( ~component, (props) => make(~info=settingsInfoFromJs(props##info), [||]) );
  • 17. type postInfo = {. “text”: string, “timeLeft”: number }; let postInfoFromJs = (jsInfo : postInfo) => { text: jsInfo##text, timeLeft: jsInfo##timeLeft }; const examplePosting = { “text”: “description of posting”, “timeLeft”: 200 }; Defining TypesPromotedPost.re App.js
  • 18. What about GraphQL 🤔 Typed Query Language Strong Reason support
  • 20. npm install graphql_ppx npm install reason_apollo { "bs-dependencies": [ "reason-react", “reason-apollo" ], "ppx-flags": [ "./node_modules/graphql_ppx/ppx -ast-out" ], } bsconfig.json Adding GraphQL to your 🚀
  • 21. Separation through GraphQL module PromotedPostQuery = [%graphql {| query getPromotedPosts { info { text timeLeft } } |}]; let promotedPosts = PromotedPostQuery.make(()); GqlPost.re
  • 22. Separation through GraphQL let component = ReasonReact.statelessComponent("PromotedPost"); [@bs.module "react-apollo"] external gql: 'a => [@bs] ReasonReact.reactClass => ReasonReact.reactClass = "graphql"; let wrap = (gql (promotedPosts##query)); let default = [@bs] wrap (ReasonReact.wrapReasonForJs( ~component, (props : {.. "data": {.. "data": TodosQuery.t, "loading": Js.boolean, } }) => make(~result=props, [||]) ) )); GqlPost.re
  • 23. Separation through GraphQL let make = (~result, _children) => { ...component, render: (self) => if(Js.to_bool (result##data##loading)){ <div> <String text="Loading"/> </div> } else { let text = result##data##info##text; let timeLeft = result##data##info##timeLeft; <div> <Post text=text timeLeft=timeLeft /> </div> } }; GqlPost.re
  • 24. A Possible API module PromotedPostQuery = [%graphql {| query getPromotedPosts { info { text timeLeft } } |}]; let make = (~result, _children) => { ...component, render: (self) => if(Js.to_bool (result##loading)){ <div> <String text="Loading"/> </div> } else { let text = result##data##info##text; let timeLeft = result##data##info##timeLeft; <div> <Post text=info.text timeLeft=info.timeLeft /> </div> } }; let default = ReasonApollo.graphql (PromotedPostsQuery) {"PromotedPost", make);
  • 25. Let’s collaborate! Evans Hauser @evanshauser evans@apollograpql.com • Next Steps: • Ensure that your types work across the client server boundary • Manage client-side state with apollo-link-state Huge thank you to Ben Souci for his help putting together this talk!