SlideShare a Scribd company logo
1 of 63
Download to read offline
Nikolas Burk 👋
Developer at Graphcool
$ whoami
@nikolasburk
Launch Week 🚀
Product Hunt > 1000 upvotesHacker News #1
Getting Started with
Relay Modern
1. Relay - A Brief History
2. Data Fetching
3. Mutations
4. More Features in Relay Modern
Agenda
@nikolasburk
Relay - A Brief History
@nikolasburk
Relay - A Brief History
@nikolasburk
01/2015
1st talk about Relay
@React.js Conf 2015
2012
FB starts using
GraphQL
02/2015
🗣
Announcing Relay will
be open-source
08/2015
Relay is
open-source 🎉
08/2016
🗣
Announcing plans
for “Relay 2”
04/2017
Introducing
Relay Modern
GraphQL Clients
- homegrown by Facebook
- main goal: performance
- learning curve
- community-driven
- main goal: flexibility
- easy-to-get-started
@nikolasburk
Data Fetching
@nikolasburk
Traditional Data Fetching with REST
1. construct & send HTTP request
(e.g. with fetch)
2. receive & parse server response
3. store data locally
4. display data in UI
😐
@nikolasburk
Declarative Data Fetching with GraphQL
1. describe data dependencies
2. display data in UI
😍
@nikolasburk
Relay’s core idea is to couple a view
component with its data dependencies
@nikolasburk
Example:
Simple Instagram App
@nikolasburk
Post Post
ListPage
App
@nikolasburk
class Post extends React.Component {
render () {
return (
<div>
<img
src={this.props.post.imageUrl}
/>
<div>
{this.props.post.description}
</div>
</div>
)
}
}
export default createFragmentContainer(Post, graphql`
fragment Post_post on Post {
id
description
imageUrl
}
`)
Post.js
@nikolasburk
class Post extends React.Component {
render () {
return (
<div>
<img
src={this.props.post.imageUrl}
/>
<div>
{this.props.post.description}
</div>
</div>
)
}
}
export default createFragmentContainer(Post, graphql`
fragment Post_post on Post {
id
description
imageUrl
}
`)
Post.js
@nikolasburk
class Post extends React.Component {
render () {
return (
<div>
<img
src={this.props.post.imageUrl}
/>
<div>
{this.props.post.description}
</div>
</div>
)
}
}
export default createFragmentContainer(Post, graphql`
fragment Post_post on Post {
id
description
imageUrl
}
`)
Post.js
@nikolasburk
class Post extends React.Component {
render () {
return (
<div>
<img
src={this.props.post.imageUrl}
/>
<div>
{this.props.post.description}
</div>
</div>
)
}
}
export default createFragmentContainer(Post, graphql`
fragment Post_post on Post {
id
description
imageUrl
}
`)
Post.js
@nikolasburk
class Post extends React.Component {
render () {
return (
<div>
<img
src={this.props.post.imageUrl}
/>
<div>
{this.props.post.description}
</div>
</div>
)
}
}
export default createFragmentContainer(Post, graphql`
fragment Post_post on Post {
id
description
imageUrl
}
`)
Post.js
@nikolasburk
class Post extends React.Component {
render () {
return (
<div>
<img
src={this.props.post.imageUrl}
/>
<div>
{this.props.post.description}
</div>
</div>
)
}
}
export default createFragmentContainer(Post, graphql`
fragment Post_post on Post {
id
description
imageUrl
}
`)
Post.js
@nikolasburk
export default createFragmentContainer(ListPage, graphql`
fragment ListPage_viewer on Viewer {
allPosts @connection(key: “ListPage_allPosts") {
edges {
node {
…Post_post # from Post.js
}
}
}
}
`)
class ListPage extends React.Component {
render () {
return (
<div>
{this.props.viewer.allPosts.edges.map(({node}) =>
<Post key={node.id} post={node} />
)}
</div>
)
}
}
ListPage.js
@nikolasburk
export default createFragmentContainer(ListPage, graphql`
fragment ListPage_viewer on Viewer {
allPosts @connection(key: “ListPage_allPosts") {
edges {
node {
...Post_post
}
}
}
}
`)
class ListPage extends React.Component {
render () {
return (
<div>
{this.props.viewer.allPosts.edges.map(({node}) =>
<Post key={node.id} post={node} />
)}
</div>
)
}
}
ListPage.js
@nikolasburk
export default createFragmentContainer(ListPage, graphql`
fragment ListPage_viewer on Viewer {
allPosts @connection(key: “ListPage_allPosts") {
edges {
node {
...Post_post
}
}
}
}
`)
class ListPage extends React.Component {
render () {
return (
<div>
{this.props.viewer.allPosts.edges.map(({node}) =>
<Post key={node.id} post={node} />
)}
</div>
)
}
}
ListPage.js
@nikolasburk
export default createFragmentContainer(ListPage, graphql`
fragment ListPage_viewer on Viewer {
allPosts @connection(key: “ListPage_allPosts") {
edges {
node {
...Post_post
}
}
}
}
`)
class ListPage extends React.Component {
render () {
return (
<div>
{this.props.viewer.allPosts.edges.map(({node}) =>
<Post key={node.id} post={node} />
)}
</div>
)
}
}
ListPage.js
@nikolasburk
export default createFragmentContainer(ListPage, graphql`
fragment ListPage_viewer on Viewer {
allPosts @connection(key: “ListPage_allPosts") {
edges {
node {
...Post_post
}
}
}
}
`)
class ListPage extends React.Component {
render () {
return (
<div>
{this.props.viewer.allPosts.edges.map(({node}) =>
<Post key={node.id} post={node} />
)}
</div>
)
}
}
ListPage.js
@nikolasburk
export default createFragmentContainer(ListPage, graphql`
fragment ListPage_viewer on Viewer {
allPosts @connection(key: "ListPage_allPosts") {
edges {
node {
...Post_post
}
}
}
}
`)
class ListPage extends React.Component {
render () {
return (
<div>
{this.props.viewer.allPosts.edges.map(({node}) =>
<Post key={node.id} post={node} />
)}
</div>
)
}
}
ListPage.js
@nikolasburk
The QueryRenderer
QueryRenderer is the root of a Relay tree.
It takes a query, fetches the data
and calls the render callback.
@nikolasburk
class App extends Component {
render() {
return (
<QueryRenderer
environment={environment}
query={AppAllPostQuery}
render={({error, props}) => {
if (error) {
return <div>{error.message}</div>
} else if (props) {
return <ListPage viewer={props.viewer} />
}
return <div>Loading</div>
}}
/>
)
}
}
const AppAllPostQuery = graphql`
query AppAllPostQuery {
viewer {
…ListPage_viewer
}
}
`
App.js
@nikolasburk
class App extends Component {
render() {
return (
<QueryRenderer
environment={environment}
query={AppAllPostQuery}
render={({error, props}) => {
if (error) {
return <div>{error.message}</div>
} else if (props) {
return <ListPage viewer={props.viewer} />
}
return <div>Loading</div>
}}
/>
)
}
}
const AppAllPostQuery = graphql`
query AppAllPostQuery {
viewer {
…ListPage_viewer
}
}
`
App.js
@nikolasburk
class App extends Component {
render() {
return (
<QueryRenderer
environment={environment}
query={AppAllPostQuery}
render={({error, props}) => {
if (error) {
return <div>{error.message}</div>
} else if (props) {
return <ListPage viewer={props.viewer} />
}
return <div>Loading</div>
}}
/>
)
}
}
const AppAllPostQuery = graphql`
query AppAllPostQuery {
viewer {
…ListPage_viewer # from ListPage.js
}
}
`
App.js
@nikolasburk
class App extends Component {
render() {
return (
<QueryRenderer
environment={environment}
query={AppAllPostQuery}
render={({error, props}) => {
if (error) {
return <div>{error.message}</div>
} else if (props) {
return <ListPage viewer={props.viewer} />
}
return <div>Loading</div>
}}
/>
)
}
}
const AppAllPostQuery = graphql`
query AppAllPostQuery {
viewer {
…ListPage_viewer
}
}
`
ListPage.js
@nikolasburk
class App extends Component {
render() {
return (
<QueryRenderer
environment={environment}
query={AppAllPostQuery}
render={({error, props}) => {
if (error) {
return <div>{error.message}</div>
} else if (props) {
return <ListPage viewer={props.viewer} />
}
return <div>Loading</div>
}}
/>
)
}
}
const AppAllPostQuery = graphql`
query AppAllPostQuery {
viewer {
…ListPage_viewer
}
}
`
ListPage.js
@nikolasburk
class App extends Component {
render() {
return (
<QueryRenderer
environment={environment}
query={AppAllPostQuery}
render={({error, props}) => {
if (error) {
return <div>{error.message}</div>
} else if (props) {
return <ListPage viewer={props.viewer} />
}
return <div>Loading</div>
}}
/>
)
}
}
const AppAllPostQuery = graphql`
query AppAllPostQuery {
viewer {
…ListPage_viewer
}
}
`
ListPage.js
@nikolasburk
class App extends Component {
render() {
return (
<QueryRenderer
environment={environment}
query={AppAllPostQuery}
render={({error, props}) => {
if (error) {
return <div>{error.message}</div>
} else if (props) {
return <ListPage viewer={props.viewer} />
}
return <div>Loading</div>
}}
/>
)
}
}
const AppAllPostQuery = graphql`
query AppAllPostQuery {
viewer {
…ListPage_viewer
}
}
`
ListPage.js
@nikolasburk
Mutations
@nikolasburk
Mutations in Relay Modern
const {commitMutation} = require('react-relay')
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
const mutation = graphql`
mutation CreatePostMutation($input: CreatePostInput!) {
createPost(input: $input) {
post {
id
description
imageUrl
}
}
}
`
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
}
)
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
const variables = {
input: {
description: “Nice Sunset”,
imageUrl: “www.example.org/sunset.jpg”,
}
}
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
}
)
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
}
)
@nikolasburk
Updating the Cache
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
updater: (proxyStore) => {
const createPostField = proxyStore.getRootField('createPost')
const newPost = createPostField.getLinkedRecord('post')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
const mutation = graphql`
mutation CreatePostMutation($input: CreatePostInput!) {
createPost(input: $input) {
post {
id
description
imageUrl
}
}
}
`
@nikolasburk
Updating the Cache
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
updater: (proxyStore) => {
const createPostField = proxyStore.getRootField('createPost')
const newPost = createPostField.getLinkedRecord('post')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
const mutation = graphql`
mutation CreatePostMutation($input: CreatePostInput!) {
createPost(input: $input) {
post {
id
description
imageUrl
}
}
}
`
@nikolasburk
Updating the Cache
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
updater: (proxyStore) => {
const createPostField = proxyStore.getRootField('createPost')
const newPost = createPostField.getLinkedRecord('post')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
const mutation = graphql`
mutation CreatePostMutation($input: CreatePostInput!) {
createPost(input: $input) {
post {
id
description
imageUrl
}
}
}
`
@nikolasburk
Updating the Cache
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
updater: (proxyStore) => {
const createPostField = proxyStore.getRootField('createPost')
const newPost = createPostField.getLinkedRecord('post')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
fragment ListPage_viewer on Viewer {
allPosts @connection(key: "ListPage_allPosts") {
edges {
node {
...Post_post
}
}
}
}
@nikolasburk
Updating the Cache
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
updater: (proxyStore) => {
const createPostField = proxyStore.getRootField('createPost')
const newPost = createPostField.getLinkedRecord('post')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
fragment ListPage_viewer on Viewer {
allPosts @connection(key: "ListPage_allPosts") {
edges {
node {
...Post_post
}
}
}
}
@nikolasburk
Mutations in Relay Modern
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
}
)
@nikolasburk
Updating the Cache (Optimistically)
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
optimisticUpdater: (proxyStore) => {
const id = 'client:newPost:' + tempID++
const newPost = proxyStore.create(id, 'Post')
newPost.setValue(description, 'description')
newPost.setValue(imageUrl, 'imageUrl')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
@nikolasburk
Updating the Cache (Optimistically)
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
optimisticUpdater: (proxyStore) => {
const id = 'client:newPost:' + tempID++
const newPost = proxyStore.create(id, 'Post')
newPost.setValue(description, 'description')
newPost.setValue(imageUrl, 'imageUrl')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
@nikolasburk
Updating the Cache (Optimistically)
commitMutation(
environment: Environment,
config: {
mutation: GraphQLTaggedNode,
variables: Variables,
onCompleted: (response) => void,
onError: (error) => void,
updater: (store) => void,
optimisticUpdater: (store) => void,
},
)
optimisticUpdater: (proxyStore) => {
const id = 'client:newPost:' + tempID++
const newPost = proxyStore.create(id, 'Post')
newPost.setValue(description, 'description')
newPost.setValue(imageUrl, 'imageUrl')
const viewerProxy = proxyStore.get(viewerId)
const connection =
ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts')
ConnectionHandler.insertEdgeAfter(connection, newPost)
}
@nikolasburk
More Features in Relay Modern
@nikolasburk
The Relay Environment 🌍
….bundles together the configuration, cache storage, and
network-handling that Relay needs in order to operate.
const environment = new Environment({
network,
store,
})
@nikolasburk
GraphQL Subscriptions ⚡
@nikolasburk
….allow to receive realtime events from the server.
Client Schema Extensions 💼
@nikolasburk
….allow to store client state.
extend type Post {
hasViewerSeen: Boolean
}
Garbage Collection 🗑
@nikolasburk
… removes objects from memory before the
JS Garbage Collector runs.
Compatibility Mode 🎯
@nikolasburk
… allows to incrementally update an application
from Relay Classic to Relay Modern.
Resources 📚
• Quickstart (Sample Code)
https://github.com/graphcool-examples/react-graphql/tree/master/quickstart-with-relay-modern
• 1st talk about Relay @ React.JS Conf 2015 (Video)
https://www.youtube.com/watch?v=9sc8Pyc51uU
• Introducing Relay and GraphQL (Article)
https://facebook.github.io/react/blog/2015/02/20/introducing-relay-and-graphql.html
• Building Relay Modern (Article)
https://wincent.com/blog/relay-modern
• Getting Started with Relay Modern (Tutorial)
https://www.graph.cool/docs/tutorials/relay-modern-getting-started-woodito7ug/
@nikolasburk
Community 🙌
• slack.graph.cool (> 2000 members)
• GraphQL Weekly Newsletter
• GraphQL Radio Podcast
@nikolasburk
We’re hiring!
www.graph.cool/jobs
@nikolasburk
Thank you! 🙇
… any questions?
@nikolasburk

More Related Content

What's hot

Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native Way
Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native WayMigrating Airflow-based Apache Spark Jobs to Kubernetes – the Native Way
Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native WayDatabricks
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaGuido Schmutz
 
Event sourcing - what could possibly go wrong ? Devoxx PL 2021
Event sourcing  - what could possibly go wrong ? Devoxx PL 2021Event sourcing  - what could possibly go wrong ? Devoxx PL 2021
Event sourcing - what could possibly go wrong ? Devoxx PL 2021Andrzej Ludwikowski
 
Data all over the place! How SQL and Apache Calcite bring sanity to streaming...
Data all over the place! How SQL and Apache Calcite bring sanity to streaming...Data all over the place! How SQL and Apache Calcite bring sanity to streaming...
Data all over the place! How SQL and Apache Calcite bring sanity to streaming...Julian Hyde
 
Extending Apache Spark – Beyond Spark Session Extensions
Extending Apache Spark – Beyond Spark Session ExtensionsExtending Apache Spark – Beyond Spark Session Extensions
Extending Apache Spark – Beyond Spark Session ExtensionsDatabricks
 
Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch - Dynami...
Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch -  Dynami...Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch -  Dynami...
Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch - Dynami...Flink Forward
 
Deep dive into stateful stream processing in structured streaming by Tathaga...
Deep dive into stateful stream processing in structured streaming  by Tathaga...Deep dive into stateful stream processing in structured streaming  by Tathaga...
Deep dive into stateful stream processing in structured streaming by Tathaga...Databricks
 
Interactive Kafka Streams
Interactive Kafka StreamsInteractive Kafka Streams
Interactive Kafka Streamsconfluent
 
Samza 0.13 meetup slide v1.0.pptx
Samza 0.13 meetup slide   v1.0.pptxSamza 0.13 meetup slide   v1.0.pptx
Samza 0.13 meetup slide v1.0.pptxYi Pan
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS and Apache KafkaSolutions for bi-directional integration between Oracle RDBMS and Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS and Apache KafkaGuido Schmutz
 
A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...
A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...
A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...Databricks
 
Component level caching with react
Component level caching with reactComponent level caching with react
Component level caching with reactAnusheelSingh2
 
Performance Analysis and Optimizations for Kafka Streams Applications
Performance Analysis and Optimizations for Kafka Streams ApplicationsPerformance Analysis and Optimizations for Kafka Streams Applications
Performance Analysis and Optimizations for Kafka Streams ApplicationsGuozhang Wang
 
Distributed Real-Time Stream Processing: Why and How 2.0
Distributed Real-Time Stream Processing:  Why and How 2.0Distributed Real-Time Stream Processing:  Why and How 2.0
Distributed Real-Time Stream Processing: Why and How 2.0Petr Zapletal
 
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and TypescriptMongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and TypescriptMongoDB
 
Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...
Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...
Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...Databricks
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryDatabricks
 

What's hot (18)

Ajax
AjaxAjax
Ajax
 
Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native Way
Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native WayMigrating Airflow-based Apache Spark Jobs to Kubernetes – the Native Way
Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native Way
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
 
Event sourcing - what could possibly go wrong ? Devoxx PL 2021
Event sourcing  - what could possibly go wrong ? Devoxx PL 2021Event sourcing  - what could possibly go wrong ? Devoxx PL 2021
Event sourcing - what could possibly go wrong ? Devoxx PL 2021
 
Data all over the place! How SQL and Apache Calcite bring sanity to streaming...
Data all over the place! How SQL and Apache Calcite bring sanity to streaming...Data all over the place! How SQL and Apache Calcite bring sanity to streaming...
Data all over the place! How SQL and Apache Calcite bring sanity to streaming...
 
Extending Apache Spark – Beyond Spark Session Extensions
Extending Apache Spark – Beyond Spark Session ExtensionsExtending Apache Spark – Beyond Spark Session Extensions
Extending Apache Spark – Beyond Spark Session Extensions
 
Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch - Dynami...
Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch -  Dynami...Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch -  Dynami...
Flink Forward SF 2017: David Hardwick, Sean Hester & David Brelloch - Dynami...
 
Deep dive into stateful stream processing in structured streaming by Tathaga...
Deep dive into stateful stream processing in structured streaming  by Tathaga...Deep dive into stateful stream processing in structured streaming  by Tathaga...
Deep dive into stateful stream processing in structured streaming by Tathaga...
 
Interactive Kafka Streams
Interactive Kafka StreamsInteractive Kafka Streams
Interactive Kafka Streams
 
Samza 0.13 meetup slide v1.0.pptx
Samza 0.13 meetup slide   v1.0.pptxSamza 0.13 meetup slide   v1.0.pptx
Samza 0.13 meetup slide v1.0.pptx
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS and Apache KafkaSolutions for bi-directional integration between Oracle RDBMS and Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafka
 
A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...
A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...
A Deep Dive into Stateful Stream Processing in Structured Streaming with Tath...
 
Component level caching with react
Component level caching with reactComponent level caching with react
Component level caching with react
 
Performance Analysis and Optimizations for Kafka Streams Applications
Performance Analysis and Optimizations for Kafka Streams ApplicationsPerformance Analysis and Optimizations for Kafka Streams Applications
Performance Analysis and Optimizations for Kafka Streams Applications
 
Distributed Real-Time Stream Processing: Why and How 2.0
Distributed Real-Time Stream Processing:  Why and How 2.0Distributed Real-Time Stream Processing:  Why and How 2.0
Distributed Real-Time Stream Processing: Why and How 2.0
 
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and TypescriptMongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
 
Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...
Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...
Deep Dive into Stateful Stream Processing in Structured Streaming with Tathag...
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 

Similar to Getting Started with Relay Modern

Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Elyse Kolker Gordon
 
2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & WebpackCodifly
 
Learning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User InterfacesLearning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User InterfacesKen Wheeler
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Robert DeLuca
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux IntroductionNikolaus Graf
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platformsAyush Sharma
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!Sébastien Levert
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Luciano Mammino
 
React on Rails - RailsConf 2017 (Phoenix)
 React on Rails - RailsConf 2017 (Phoenix) React on Rails - RailsConf 2017 (Phoenix)
React on Rails - RailsConf 2017 (Phoenix)Jo Cranford
 
React.js: You deserve to know about it
React.js: You deserve to know about itReact.js: You deserve to know about it
React.js: You deserve to know about itAnderson Aguiar
 
Dive into React Performance
Dive into React PerformanceDive into React Performance
Dive into React PerformanceChing Ting Wu
 
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastAtlassian
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterKaty Slemon
 
Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?Erik-Berndt Scheper
 
Office 365 Groups and Tasks API - Getting Started
Office 365 Groups and Tasks API - Getting StartedOffice 365 Groups and Tasks API - Getting Started
Office 365 Groups and Tasks API - Getting StartedDragan Panjkov
 
Time to React!
Time to React!Time to React!
Time to React!STX Next
 

Similar to Getting Started with Relay Modern (20)

React js
React jsReact js
React js
 
React 101
React 101React 101
React 101
 
Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017
 
2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack
 
Learning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User InterfacesLearning React: Facebook's Javascript Library For Building User Interfaces
Learning React: Facebook's Javascript Library For Building User Interfaces
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!
 
React lecture
React lectureReact lecture
React lecture
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
 
React on Rails - RailsConf 2017 (Phoenix)
 React on Rails - RailsConf 2017 (Phoenix) React on Rails - RailsConf 2017 (Phoenix)
React on Rails - RailsConf 2017 (Phoenix)
 
React.js: You deserve to know about it
React.js: You deserve to know about itReact.js: You deserve to know about it
React.js: You deserve to know about it
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Dive into React Performance
Dive into React PerformanceDive into React Performance
Dive into React Performance
 
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilter
 
Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?Big Data processing with Spark, Scala or Java?
Big Data processing with Spark, Scala or Java?
 
Office 365 Groups and Tasks API - Getting Started
Office 365 Groups and Tasks API - Getting StartedOffice 365 Groups and Tasks API - Getting Started
Office 365 Groups and Tasks API - Getting Started
 
Time to React!
Time to React!Time to React!
Time to React!
 

More from Nikolas Burk

Next-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and PrismaNext-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and PrismaNikolas Burk
 
Code-first GraphQL Server Development with Prisma
Code-first  GraphQL Server Development with PrismaCode-first  GraphQL Server Development with Prisma
Code-first GraphQL Server Development with PrismaNikolas Burk
 
GraphQL & Prisma from Scratch
GraphQL & Prisma from ScratchGraphQL & Prisma from Scratch
GraphQL & Prisma from ScratchNikolas Burk
 
GraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & ContentfulGraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & ContentfulNikolas Burk
 
Managing GraphQL servers with AWS Fargate & Prisma Cloud
Managing GraphQL servers  with AWS Fargate & Prisma CloudManaging GraphQL servers  with AWS Fargate & Prisma Cloud
Managing GraphQL servers with AWS Fargate & Prisma CloudNikolas Burk
 
Building GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & PrismaBuilding GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & PrismaNikolas Burk
 
The GraphQL Ecosystem in 2018
The GraphQL Ecosystem in 2018The GraphQL Ecosystem in 2018
The GraphQL Ecosystem in 2018Nikolas Burk
 
Building Serverless GraphQL Backends
Building Serverless GraphQL BackendsBuilding Serverless GraphQL Backends
Building Serverless GraphQL BackendsNikolas Burk
 
GraphQL Subscriptions
GraphQL SubscriptionsGraphQL Subscriptions
GraphQL SubscriptionsNikolas Burk
 
The Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend ArchitectureThe Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend ArchitectureNikolas Burk
 
State Management & Unidirectional Data Flow
State Management & Unidirectional Data FlowState Management & Unidirectional Data Flow
State Management & Unidirectional Data FlowNikolas Burk
 
Diving into GraphQL, React & Apollo
Diving into GraphQL, React & ApolloDiving into GraphQL, React & Apollo
Diving into GraphQL, React & ApolloNikolas Burk
 
Authentication, Authorization & Error Handling with GraphQL
Authentication, Authorization & Error Handling with GraphQLAuthentication, Authorization & Error Handling with GraphQL
Authentication, Authorization & Error Handling with GraphQLNikolas Burk
 
Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions
Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions
Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions Nikolas Burk
 
Building a Realtime Chat with React & GraphQL Subscriptions
Building a Realtime Chat with React & GraphQL Subscriptions Building a Realtime Chat with React & GraphQL Subscriptions
Building a Realtime Chat with React & GraphQL Subscriptions Nikolas Burk
 
REST in Peace - Using GraphQL with Apollo on iOS
REST in Peace - Using GraphQL with Apollo on iOSREST in Peace - Using GraphQL with Apollo on iOS
REST in Peace - Using GraphQL with Apollo on iOSNikolas Burk
 

More from Nikolas Burk (17)

Next-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and PrismaNext-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and Prisma
 
Code-first GraphQL Server Development with Prisma
Code-first  GraphQL Server Development with PrismaCode-first  GraphQL Server Development with Prisma
Code-first GraphQL Server Development with Prisma
 
GraphQL & Prisma from Scratch
GraphQL & Prisma from ScratchGraphQL & Prisma from Scratch
GraphQL & Prisma from Scratch
 
GraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & ContentfulGraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & Contentful
 
Managing GraphQL servers with AWS Fargate & Prisma Cloud
Managing GraphQL servers  with AWS Fargate & Prisma CloudManaging GraphQL servers  with AWS Fargate & Prisma Cloud
Managing GraphQL servers with AWS Fargate & Prisma Cloud
 
Building GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & PrismaBuilding GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & Prisma
 
The GraphQL Ecosystem in 2018
The GraphQL Ecosystem in 2018The GraphQL Ecosystem in 2018
The GraphQL Ecosystem in 2018
 
React & GraphQL
React & GraphQLReact & GraphQL
React & GraphQL
 
Building Serverless GraphQL Backends
Building Serverless GraphQL BackendsBuilding Serverless GraphQL Backends
Building Serverless GraphQL Backends
 
GraphQL Subscriptions
GraphQL SubscriptionsGraphQL Subscriptions
GraphQL Subscriptions
 
The Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend ArchitectureThe Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend Architecture
 
State Management & Unidirectional Data Flow
State Management & Unidirectional Data FlowState Management & Unidirectional Data Flow
State Management & Unidirectional Data Flow
 
Diving into GraphQL, React & Apollo
Diving into GraphQL, React & ApolloDiving into GraphQL, React & Apollo
Diving into GraphQL, React & Apollo
 
Authentication, Authorization & Error Handling with GraphQL
Authentication, Authorization & Error Handling with GraphQLAuthentication, Authorization & Error Handling with GraphQL
Authentication, Authorization & Error Handling with GraphQL
 
Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions
Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions
Building a Realtime Chat with React Native (Expo) & GraphQL Subscriptions
 
Building a Realtime Chat with React & GraphQL Subscriptions
Building a Realtime Chat with React & GraphQL Subscriptions Building a Realtime Chat with React & GraphQL Subscriptions
Building a Realtime Chat with React & GraphQL Subscriptions
 
REST in Peace - Using GraphQL with Apollo on iOS
REST in Peace - Using GraphQL with Apollo on iOSREST in Peace - Using GraphQL with Apollo on iOS
REST in Peace - Using GraphQL with Apollo on iOS
 

Recently uploaded

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 

Recently uploaded (20)

The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 

Getting Started with Relay Modern

  • 1.
  • 2.
  • 3. Nikolas Burk 👋 Developer at Graphcool $ whoami @nikolasburk
  • 4. Launch Week 🚀 Product Hunt > 1000 upvotesHacker News #1
  • 6. 1. Relay - A Brief History 2. Data Fetching 3. Mutations 4. More Features in Relay Modern Agenda @nikolasburk
  • 7. Relay - A Brief History @nikolasburk
  • 8. Relay - A Brief History @nikolasburk 01/2015 1st talk about Relay @React.js Conf 2015 2012 FB starts using GraphQL 02/2015 🗣 Announcing Relay will be open-source 08/2015 Relay is open-source 🎉 08/2016 🗣 Announcing plans for “Relay 2” 04/2017 Introducing Relay Modern
  • 9. GraphQL Clients - homegrown by Facebook - main goal: performance - learning curve - community-driven - main goal: flexibility - easy-to-get-started @nikolasburk
  • 11. Traditional Data Fetching with REST 1. construct & send HTTP request (e.g. with fetch) 2. receive & parse server response 3. store data locally 4. display data in UI 😐 @nikolasburk
  • 12. Declarative Data Fetching with GraphQL 1. describe data dependencies 2. display data in UI 😍 @nikolasburk
  • 13. Relay’s core idea is to couple a view component with its data dependencies @nikolasburk
  • 16. class Post extends React.Component { render () { return ( <div> <img src={this.props.post.imageUrl} /> <div> {this.props.post.description} </div> </div> ) } } export default createFragmentContainer(Post, graphql` fragment Post_post on Post { id description imageUrl } `) Post.js @nikolasburk
  • 17. class Post extends React.Component { render () { return ( <div> <img src={this.props.post.imageUrl} /> <div> {this.props.post.description} </div> </div> ) } } export default createFragmentContainer(Post, graphql` fragment Post_post on Post { id description imageUrl } `) Post.js @nikolasburk
  • 18. class Post extends React.Component { render () { return ( <div> <img src={this.props.post.imageUrl} /> <div> {this.props.post.description} </div> </div> ) } } export default createFragmentContainer(Post, graphql` fragment Post_post on Post { id description imageUrl } `) Post.js @nikolasburk
  • 19. class Post extends React.Component { render () { return ( <div> <img src={this.props.post.imageUrl} /> <div> {this.props.post.description} </div> </div> ) } } export default createFragmentContainer(Post, graphql` fragment Post_post on Post { id description imageUrl } `) Post.js @nikolasburk
  • 20. class Post extends React.Component { render () { return ( <div> <img src={this.props.post.imageUrl} /> <div> {this.props.post.description} </div> </div> ) } } export default createFragmentContainer(Post, graphql` fragment Post_post on Post { id description imageUrl } `) Post.js @nikolasburk
  • 21. class Post extends React.Component { render () { return ( <div> <img src={this.props.post.imageUrl} /> <div> {this.props.post.description} </div> </div> ) } } export default createFragmentContainer(Post, graphql` fragment Post_post on Post { id description imageUrl } `) Post.js @nikolasburk
  • 22. export default createFragmentContainer(ListPage, graphql` fragment ListPage_viewer on Viewer { allPosts @connection(key: “ListPage_allPosts") { edges { node { …Post_post # from Post.js } } } } `) class ListPage extends React.Component { render () { return ( <div> {this.props.viewer.allPosts.edges.map(({node}) => <Post key={node.id} post={node} /> )} </div> ) } } ListPage.js @nikolasburk
  • 23. export default createFragmentContainer(ListPage, graphql` fragment ListPage_viewer on Viewer { allPosts @connection(key: “ListPage_allPosts") { edges { node { ...Post_post } } } } `) class ListPage extends React.Component { render () { return ( <div> {this.props.viewer.allPosts.edges.map(({node}) => <Post key={node.id} post={node} /> )} </div> ) } } ListPage.js @nikolasburk
  • 24. export default createFragmentContainer(ListPage, graphql` fragment ListPage_viewer on Viewer { allPosts @connection(key: “ListPage_allPosts") { edges { node { ...Post_post } } } } `) class ListPage extends React.Component { render () { return ( <div> {this.props.viewer.allPosts.edges.map(({node}) => <Post key={node.id} post={node} /> )} </div> ) } } ListPage.js @nikolasburk
  • 25. export default createFragmentContainer(ListPage, graphql` fragment ListPage_viewer on Viewer { allPosts @connection(key: “ListPage_allPosts") { edges { node { ...Post_post } } } } `) class ListPage extends React.Component { render () { return ( <div> {this.props.viewer.allPosts.edges.map(({node}) => <Post key={node.id} post={node} /> )} </div> ) } } ListPage.js @nikolasburk
  • 26. export default createFragmentContainer(ListPage, graphql` fragment ListPage_viewer on Viewer { allPosts @connection(key: “ListPage_allPosts") { edges { node { ...Post_post } } } } `) class ListPage extends React.Component { render () { return ( <div> {this.props.viewer.allPosts.edges.map(({node}) => <Post key={node.id} post={node} /> )} </div> ) } } ListPage.js @nikolasburk
  • 27. export default createFragmentContainer(ListPage, graphql` fragment ListPage_viewer on Viewer { allPosts @connection(key: "ListPage_allPosts") { edges { node { ...Post_post } } } } `) class ListPage extends React.Component { render () { return ( <div> {this.props.viewer.allPosts.edges.map(({node}) => <Post key={node.id} post={node} /> )} </div> ) } } ListPage.js @nikolasburk
  • 28. The QueryRenderer QueryRenderer is the root of a Relay tree. It takes a query, fetches the data and calls the render callback. @nikolasburk
  • 29. class App extends Component { render() { return ( <QueryRenderer environment={environment} query={AppAllPostQuery} render={({error, props}) => { if (error) { return <div>{error.message}</div> } else if (props) { return <ListPage viewer={props.viewer} /> } return <div>Loading</div> }} /> ) } } const AppAllPostQuery = graphql` query AppAllPostQuery { viewer { …ListPage_viewer } } ` App.js @nikolasburk
  • 30. class App extends Component { render() { return ( <QueryRenderer environment={environment} query={AppAllPostQuery} render={({error, props}) => { if (error) { return <div>{error.message}</div> } else if (props) { return <ListPage viewer={props.viewer} /> } return <div>Loading</div> }} /> ) } } const AppAllPostQuery = graphql` query AppAllPostQuery { viewer { …ListPage_viewer } } ` App.js @nikolasburk
  • 31. class App extends Component { render() { return ( <QueryRenderer environment={environment} query={AppAllPostQuery} render={({error, props}) => { if (error) { return <div>{error.message}</div> } else if (props) { return <ListPage viewer={props.viewer} /> } return <div>Loading</div> }} /> ) } } const AppAllPostQuery = graphql` query AppAllPostQuery { viewer { …ListPage_viewer # from ListPage.js } } ` App.js @nikolasburk
  • 32. class App extends Component { render() { return ( <QueryRenderer environment={environment} query={AppAllPostQuery} render={({error, props}) => { if (error) { return <div>{error.message}</div> } else if (props) { return <ListPage viewer={props.viewer} /> } return <div>Loading</div> }} /> ) } } const AppAllPostQuery = graphql` query AppAllPostQuery { viewer { …ListPage_viewer } } ` ListPage.js @nikolasburk
  • 33. class App extends Component { render() { return ( <QueryRenderer environment={environment} query={AppAllPostQuery} render={({error, props}) => { if (error) { return <div>{error.message}</div> } else if (props) { return <ListPage viewer={props.viewer} /> } return <div>Loading</div> }} /> ) } } const AppAllPostQuery = graphql` query AppAllPostQuery { viewer { …ListPage_viewer } } ` ListPage.js @nikolasburk
  • 34. class App extends Component { render() { return ( <QueryRenderer environment={environment} query={AppAllPostQuery} render={({error, props}) => { if (error) { return <div>{error.message}</div> } else if (props) { return <ListPage viewer={props.viewer} /> } return <div>Loading</div> }} /> ) } } const AppAllPostQuery = graphql` query AppAllPostQuery { viewer { …ListPage_viewer } } ` ListPage.js @nikolasburk
  • 35. class App extends Component { render() { return ( <QueryRenderer environment={environment} query={AppAllPostQuery} render={({error, props}) => { if (error) { return <div>{error.message}</div> } else if (props) { return <ListPage viewer={props.viewer} /> } return <div>Loading</div> }} /> ) } } const AppAllPostQuery = graphql` query AppAllPostQuery { viewer { …ListPage_viewer } } ` ListPage.js @nikolasburk
  • 37. Mutations in Relay Modern const {commitMutation} = require('react-relay') commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) @nikolasburk
  • 38. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) @nikolasburk
  • 39. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) @nikolasburk
  • 40. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) const mutation = graphql` mutation CreatePostMutation($input: CreatePostInput!) { createPost(input: $input) { post { id description imageUrl } } } ` @nikolasburk
  • 41. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, } ) @nikolasburk
  • 42. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) const variables = { input: { description: “Nice Sunset”, imageUrl: “www.example.org/sunset.jpg”, } } @nikolasburk
  • 43. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, } ) @nikolasburk
  • 44. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, } ) @nikolasburk
  • 45. Updating the Cache commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) updater: (proxyStore) => { const createPostField = proxyStore.getRootField('createPost') const newPost = createPostField.getLinkedRecord('post') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } const mutation = graphql` mutation CreatePostMutation($input: CreatePostInput!) { createPost(input: $input) { post { id description imageUrl } } } ` @nikolasburk
  • 46. Updating the Cache commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) updater: (proxyStore) => { const createPostField = proxyStore.getRootField('createPost') const newPost = createPostField.getLinkedRecord('post') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } const mutation = graphql` mutation CreatePostMutation($input: CreatePostInput!) { createPost(input: $input) { post { id description imageUrl } } } ` @nikolasburk
  • 47. Updating the Cache commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) updater: (proxyStore) => { const createPostField = proxyStore.getRootField('createPost') const newPost = createPostField.getLinkedRecord('post') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } const mutation = graphql` mutation CreatePostMutation($input: CreatePostInput!) { createPost(input: $input) { post { id description imageUrl } } } ` @nikolasburk
  • 48. Updating the Cache commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) updater: (proxyStore) => { const createPostField = proxyStore.getRootField('createPost') const newPost = createPostField.getLinkedRecord('post') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } fragment ListPage_viewer on Viewer { allPosts @connection(key: "ListPage_allPosts") { edges { node { ...Post_post } } } } @nikolasburk
  • 49. Updating the Cache commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) updater: (proxyStore) => { const createPostField = proxyStore.getRootField('createPost') const newPost = createPostField.getLinkedRecord('post') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } fragment ListPage_viewer on Viewer { allPosts @connection(key: "ListPage_allPosts") { edges { node { ...Post_post } } } } @nikolasburk
  • 50. Mutations in Relay Modern commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, } ) @nikolasburk
  • 51. Updating the Cache (Optimistically) commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) optimisticUpdater: (proxyStore) => { const id = 'client:newPost:' + tempID++ const newPost = proxyStore.create(id, 'Post') newPost.setValue(description, 'description') newPost.setValue(imageUrl, 'imageUrl') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } @nikolasburk
  • 52. Updating the Cache (Optimistically) commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) optimisticUpdater: (proxyStore) => { const id = 'client:newPost:' + tempID++ const newPost = proxyStore.create(id, 'Post') newPost.setValue(description, 'description') newPost.setValue(imageUrl, 'imageUrl') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } @nikolasburk
  • 53. Updating the Cache (Optimistically) commitMutation( environment: Environment, config: { mutation: GraphQLTaggedNode, variables: Variables, onCompleted: (response) => void, onError: (error) => void, updater: (store) => void, optimisticUpdater: (store) => void, }, ) optimisticUpdater: (proxyStore) => { const id = 'client:newPost:' + tempID++ const newPost = proxyStore.create(id, 'Post') newPost.setValue(description, 'description') newPost.setValue(imageUrl, 'imageUrl') const viewerProxy = proxyStore.get(viewerId) const connection = ConnectionHandler.getConnection(viewerProxy, 'ListPage_allPosts') ConnectionHandler.insertEdgeAfter(connection, newPost) } @nikolasburk
  • 54. More Features in Relay Modern @nikolasburk
  • 55. The Relay Environment 🌍 ….bundles together the configuration, cache storage, and network-handling that Relay needs in order to operate. const environment = new Environment({ network, store, }) @nikolasburk
  • 56. GraphQL Subscriptions ⚡ @nikolasburk ….allow to receive realtime events from the server.
  • 57. Client Schema Extensions 💼 @nikolasburk ….allow to store client state. extend type Post { hasViewerSeen: Boolean }
  • 58. Garbage Collection 🗑 @nikolasburk … removes objects from memory before the JS Garbage Collector runs.
  • 59. Compatibility Mode 🎯 @nikolasburk … allows to incrementally update an application from Relay Classic to Relay Modern.
  • 60. Resources 📚 • Quickstart (Sample Code) https://github.com/graphcool-examples/react-graphql/tree/master/quickstart-with-relay-modern • 1st talk about Relay @ React.JS Conf 2015 (Video) https://www.youtube.com/watch?v=9sc8Pyc51uU • Introducing Relay and GraphQL (Article) https://facebook.github.io/react/blog/2015/02/20/introducing-relay-and-graphql.html • Building Relay Modern (Article) https://wincent.com/blog/relay-modern • Getting Started with Relay Modern (Tutorial) https://www.graph.cool/docs/tutorials/relay-modern-getting-started-woodito7ug/ @nikolasburk
  • 61. Community 🙌 • slack.graph.cool (> 2000 members) • GraphQL Weekly Newsletter • GraphQL Radio Podcast @nikolasburk
  • 63. Thank you! 🙇 … any questions? @nikolasburk