SlideShare a Scribd company logo
Types End-to-end
More Features And Fewer Bugs with GraphQL
hello, i'm stephen!
Samsara, end-to-end
Samsara, end-to-end
Samsara, end-to-end
Samsara, end-to-end
mo' features, mo' problems.
GraphQL Schema
type Device {
name: string!;
id: number!;
currentDriver: Driver;
locations: [Location!]!;
// ...
}
type Root {
device(id: number!): Device;
}
mo' features, mo' problems.
(mo' static types)
safety
editor tooling
safety
static verification at compile time and deployment
editor tooling
autocomplete, go to definition, type hints
GraphQL + TypeScript
a simple example
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
a simple example
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
plain old javascript
const DeviceNameComponent = props => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
}));
oh no
const DeviceNameComponent = props => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
}));
oh no
const DeviceNameComponent = props => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
}));
oh no
const DeviceNameComponent = props => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
}));
oh no
const DeviceNameComponent = props => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
}));
✨ typescript ✨
typing it all out (by hand)
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
typing it all out
const DeviceNameComponent = props => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
}));
typing it all out (with typescript!)
const DeviceNameComponent = (props: Props) => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryInputVariables>
(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
})
);
typing it all out with typescript!
const DeviceNameComponent = (props: Props) => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables>
(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
})
);
typing it all out with typescript!
const DeviceNameComponent = (props: Props) => {
return <div>Name: {props.graphqlValue.device.fullName}</div>;
}
export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables>
(DeviceNameComponent, () => ({
query: ...,
variables: {
deviceId: 202152006793,
},
})
);
this works pretty well, but...
a simple example
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
uh oh
query VehicleInfo($deviceId: int64, $durationMs: int64!, $endMs: int64) {
device(id: $deviceId) {
id
name
currentDriver {
id
name
}
setPoint: objectStat(statType: SET_POINT) {
intValue
}
vehicleActivityReport(duration: $durationMs, endTime: $endMs) {
tripEntries {
start { address }
end { address }
}
}
...DashcamLatestImage
...CurrentStats
}
}
uh oh uh oh
query VehicleInfo($deviceId: int64, $durationMs: int64!, $endMs: int64) {
device(id: $deviceId) {
id
name
currentDriver {
id
name
}
setPoint: objectStat(statType: SET_POINT) {
intValue
}
vehicleActivityReport(duration: $durationMs, endTime: $endMs) {
tripEntries {
start { address }
end { address }
}
}
...DashcamLatestImage
...CurrentStats
}
}
type VehicleInfoQueryVariables = {
deviceId: number,
durationMs: number,
endM?: number,
};
type VehicleInfoQueryResult = {
device: {
id: number,
name: string,
setPoint: Array<number>,
vehicleActivityReport: {
start: {
address: string,
},
end: {
address: string,
},
} >,
},
lastDashcamEvent: {
reportType: number,
triggerTime: number,
urls: {
still: string,
},
} | null,
},
hmm...
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
// generated_types.d.ts
type DeviceNameQueryInputVariables = {
id: number;
}
type DeviceNameQuery = {
device: {
name: string;
}
}
the graphql schema and typescript types can be mapped 1:1
✨ apollo-codegen ✨
what is codegen?
how does codegen work?
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
how does codegen work?
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
how does codegen work?
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
// generated_types.d.ts
type DeviceNameQueryInputVariables = {
id: number;
}
how does codegen work?
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
how does codegen work?
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
how does codegen work?
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
how does codegen work?
# server_schema.graphql:
type Device {
name: string!;
}
type Root {
device(id: number!): Device;
}
# device_name_query.graphql:
query DeviceName($id: number!) {
device(id: $id) {
name
}
}
// generated_types.d.ts
type DeviceNameQuery = {
device: {
name: string;
}
}
$ ts-node codegen.ts > schema.d.ts
typing without typing
const DeviceNameComponent = (props: Props) => {
return <div>Name: {props.graphqlValue.device.name}</div>;
}
export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables> (DeviceNameComponent, () =>
({
query: ...,
variables: {
id: 202152006793,
},
})
);
typing without typing
import { DeviceNameQuery, DeviceNameQueryVariables } from "./generated_types";
const DeviceNameComponent = (props: Props) => {
return <div>Name: {props.graphqlValue.device.name}</div>;
}
export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables> (DeviceNameComponent, () =>
({
query: ...,
variables: {
id: 202152006793,
},
})
);
data, end-to-end
shared type land
can we go further?
can we go further?
golang types
# graphqlschema/device.go
type Device struct {
Id int64
Name string
OrganizationId int64
// ...
}
type deviceArgs struct { Id int64 }
root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) {
user, err := db.Device.Get(...)
return user, err
})
golang types
# graphqlschema/device.go
type Device struct {
Id int64
Name string
OrganizationId int64
// ...
}
type deviceArgs struct { Id int64 }
root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) {
user, err := db.Device.Get(...)
return user, err
})
# server_schema.graphql:
type Device {
name: string!;
id: number;
// ...
}
type Root {
device(id: number!): Device;
}
the go type definitions and graphql schema can also be mapped 1:1
✨ thunder + reflection ✨
golang types
# graphqlschema/device.go
type Device struct {
Id int64
Name string
OrganizationId int64
// ...
}
type deviceArgs struct { Id int64 }
root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) {
user, err := db.Device.Get(...)
return user, err
})
golang types
# graphqlschema/device.go
type Device struct {
Id int64
Name string
OrganizationId int64
// ...
}
type deviceArgs struct { Id int64 }
root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) {
user, err := db.Device.Get(...)
return user, err
})
# server_schema.graphql:
type Root {
device(id: number!): Device;
}
golang types
# graphqlschema/device.go
type Device struct {
Id int64
Name string
OrganizationId int64
// ...
}
type deviceArgs struct { Id int64 }
root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) {
user, err := db.Device.Get(...)
return user, err
})
# server_schema.graphql:
type Device {
name: string!;
id: number;
// ...
}
$ go run schema_generator.go > schema.graphql
shared type land
shared type land
can we go further?
can we go further?
can we go further?
protobuf go generation
message TemperatureStat {
int64 time = 1;
double double_value = 3;
}
surprise! protobufs and go types can also, also be mapped 1:1
✨ protoc-gen-go ✨
protobuf go generation
message TemperatureStat {
int64 time = 1;
double double_value = 3;
}
protobuf go generation
message TemperatureStat {
int64 time = 1;
double double_value = 3;
}
type TemperatureStat struct {
Time int64
DoubleValue float64
}
$ protoc-gen-go > stat.pb.go
shared type land
shared type land
type once, benefit everywhere.
schemas and typings can never be out of sync.
type once, benefit everywhere.
autocomplete, go to def, outlines in your {.pb.go, .go, .graphql, .tsx}.
type once, benefit everywhere.
a type can travel from the hardware device to the web application.
type once, benefit everywhere.
available in an open source repository near you.
type once, benefit everywhere.
a powerful default. let the computer do the busy work for you.
thank you!
twitter.com/stephencwan
github.com/samsarahq/thunder
questions?
bonus slides
the tools are there! we just need to add a little grease.
Never Type
Anything
Type TypeScript from
GraphQL
Type GraphQL from
Go
Type Go from
Protobufs
Type mapping is not always 1:1
● Union Types (supported ts, graphql, but not go)
● Enums Types (supported in ts, graphql, but not go)
● Number Types (float64 only in javascript)
○ A bit of a type safety problem, but we haven't hit the bounds of float64 in production yet.
○ We could also have a different over the wire representation for dealing with this
● Nullable Types (pointer types are not quite option types)
○ Error | Null | Value vs. (Null | Value, Error)
apollo-codegen: Autocomplete
what do we get out of static type checking?
● Type Safety
● Deployment Safety
● Autocomplete, Go to Definition
GraphQL: Deployment Safety
GraphQL: Deployment Safety
protobufs cont. (grpc systems behind graphql)
rpc UpdateDriverSafetyEvents(UpdateDriverSafetyEventsRequest) returns (UpdateDriverSafetyEventsResponse) {}
message DriverSafetyEventsRequest {
int64 org_id = 1;
repeated int64 device_ids = 2;
int64 end_ms = 3;
int64 start_ms = 4;
}
message DriverSafetyEvent {
int64 device_id = 1;
int64 harsh_event_ms = 2;
HarshEvent harsh_event = 3;
SafetyEventMetadataInboxState state = 4;
}
message DriverSafetyEventsRequest {
int64 org_id = 1;
repeated int64 device_ids = 2;
int64 end_ms = 3;
can we make this nicer?
Demands: more codegen
● What else can we do?
● extracting golang comments at compile time
● apollo-codegen with a go compilation target (i.e. for a graphql consumer api
service)
Demands: Better Type Interoperability
● Steps for code generation are still a little hard
● Need better ways of providing types across the board
● Providing Types: typescript/#3136
Types End-to-End @ samsara
Types End-to-End @ samsara

More Related Content

What's hot

Java Script Best Practices
Java Script Best PracticesJava Script Best Practices
Java Script Best Practices
Enrique Juan de Dios
 
Beginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScriptBeginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScript
Stoyan Stefanov
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
Rick Beerendonk
 
All things that are not code
All things that are not codeAll things that are not code
All things that are not code
Mobile Delivery Days
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScript
ecker
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
Visual Engineering
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
Donald Sipe
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
Rainer Stropek
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
Stoyan Stefanov
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
François Sarradin
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
Kacper Gunia
 
Understanding Object Oriented Javascript - Coffee@DBG June
Understanding Object Oriented Javascript - Coffee@DBG JuneUnderstanding Object Oriented Javascript - Coffee@DBG June
Understanding Object Oriented Javascript - Coffee@DBG June
Deepu S Nath
 
Esprima - What is that
Esprima - What is thatEsprima - What is that
Esprima - What is that
Abhijeet Pawar
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
Stephen Vance
 
Javascript
JavascriptJavascript
Javascript
theacadian
 
JavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UX
JWORKS powered by Ordina
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Advanced JavaScript Concepts
Advanced JavaScript ConceptsAdvanced JavaScript Concepts
Advanced JavaScript Concepts
Naresh Kumar
 
Html and i_phone_mobile-2
Html and i_phone_mobile-2Html and i_phone_mobile-2
Html and i_phone_mobile-2
tonvanbart
 

What's hot (20)

Java Script Best Practices
Java Script Best PracticesJava Script Best Practices
Java Script Best Practices
 
Beginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScriptBeginning Object-Oriented JavaScript
Beginning Object-Oriented JavaScript
 
JavaScript 2016 for C# Developers
JavaScript 2016 for C# DevelopersJavaScript 2016 for C# Developers
JavaScript 2016 for C# Developers
 
All things that are not code
All things that are not codeAll things that are not code
All things that are not code
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScript
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Understanding Object Oriented Javascript - Coffee@DBG June
Understanding Object Oriented Javascript - Coffee@DBG JuneUnderstanding Object Oriented Javascript - Coffee@DBG June
Understanding Object Oriented Javascript - Coffee@DBG June
 
Esprima - What is that
Esprima - What is thatEsprima - What is that
Esprima - What is that
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
 
Javascript
JavascriptJavascript
Javascript
 
JavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UXJavaScript Basics and Best Practices - CC FE & UX
JavaScript Basics and Best Practices - CC FE & UX
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Advanced JavaScript Concepts
Advanced JavaScript ConceptsAdvanced JavaScript Concepts
Advanced JavaScript Concepts
 
Html and i_phone_mobile-2
Html and i_phone_mobile-2Html and i_phone_mobile-2
Html and i_phone_mobile-2
 

Similar to Types End-to-End @ samsara

Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
Tugdual Grall
 
Einführung in TypeScript
Einführung in TypeScriptEinführung in TypeScript
Einführung in TypeScript
Demian Holderegger
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
Clinton Dreisbach
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
Ted Husted
 
Dart Power Tools
Dart Power ToolsDart Power Tools
Dart Power Tools
Matt Norris
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
Jevgeni Kabanov
 
GraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedGraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learned
MarcinStachniuk
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
Ted Husted
 
What’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth LaddWhat’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth Ladd
jaxconf
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with Netbeans
Carol McDonald
 
Day 1
Day 1Day 1
node.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.ionode.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.io
Steven Beeckman
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack Support
Ben Scofield
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN Golang
Bo-Yi Wu
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
Laurent_VB
 
Dart and AngularDart
Dart and AngularDartDart and AngularDart
Dart and AngularDart
Loc Nguyen
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
AidIQ
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
Siarhei Barysiuk
 
Strongly typed web applications by Adel Salakh
 Strongly typed web applications by Adel Salakh   Strongly typed web applications by Adel Salakh
Strongly typed web applications by Adel Salakh
OdessaJS Conf
 
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
Nikolas Burk
 

Similar to Types End-to-End @ samsara (20)

Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Einführung in TypeScript
Einführung in TypeScriptEinführung in TypeScript
Einführung in TypeScript
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
 
Dart Power Tools
Dart Power ToolsDart Power Tools
Dart Power Tools
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 
GraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedGraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learned
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
 
What’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth LaddWhat’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth Ladd
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with Netbeans
 
Day 1
Day 1Day 1
Day 1
 
node.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.ionode.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.io
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack Support
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN Golang
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
Dart and AngularDart
Dart and AngularDartDart and AngularDart
Dart and AngularDart
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
 
Strongly typed web applications by Adel Salakh
 Strongly typed web applications by Adel Salakh   Strongly typed web applications by Adel Salakh
Strongly typed web applications by Adel Salakh
 
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
 

Recently uploaded

Recycled Concrete Aggregate in Construction Part II
Recycled Concrete Aggregate in Construction Part IIRecycled Concrete Aggregate in Construction Part II
Recycled Concrete Aggregate in Construction Part II
Aditya Rajan Patra
 
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student MemberIEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
VICTOR MAESTRE RAMIREZ
 
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
Yasser Mahgoub
 
Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
mamamaam477
 
22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt
KrishnaveniKrishnara1
 
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressionsKuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
Victor Morales
 
Modelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdfModelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdf
camseq
 
Generative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of contentGenerative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of content
Hitesh Mohapatra
 
A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...
nooriasukmaningtyas
 
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have oneISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
Las Vegas Warehouse
 
Understanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine LearningUnderstanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine Learning
SUTEJAS
 
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
IJECEIAES
 
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.pptUnit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
KrishnaveniKrishnara1
 
Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...
bijceesjournal
 
New techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdfNew techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdf
wisnuprabawa3
 
Properties Railway Sleepers and Test.pptx
Properties Railway Sleepers and Test.pptxProperties Railway Sleepers and Test.pptx
Properties Railway Sleepers and Test.pptx
MDSABBIROJJAMANPAYEL
 
132/33KV substation case study Presentation
132/33KV substation case study Presentation132/33KV substation case study Presentation
132/33KV substation case study Presentation
kandramariana6
 
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
IJECEIAES
 
ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024
Rahul
 
basic-wireline-operations-course-mahmoud-f-radwan.pdf
basic-wireline-operations-course-mahmoud-f-radwan.pdfbasic-wireline-operations-course-mahmoud-f-radwan.pdf
basic-wireline-operations-course-mahmoud-f-radwan.pdf
NidhalKahouli2
 

Recently uploaded (20)

Recycled Concrete Aggregate in Construction Part II
Recycled Concrete Aggregate in Construction Part IIRecycled Concrete Aggregate in Construction Part II
Recycled Concrete Aggregate in Construction Part II
 
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student MemberIEEE Aerospace and Electronic Systems Society as a Graduate Student Member
IEEE Aerospace and Electronic Systems Society as a Graduate Student Member
 
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
 
Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
 
22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt
 
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressionsKuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressions
 
Modelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdfModelagem de um CSTR com reação endotermica.pdf
Modelagem de um CSTR com reação endotermica.pdf
 
Generative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of contentGenerative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of content
 
A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...A review on techniques and modelling methodologies used for checking electrom...
A review on techniques and modelling methodologies used for checking electrom...
 
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have oneISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
 
Understanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine LearningUnderstanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine Learning
 
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
Electric vehicle and photovoltaic advanced roles in enhancing the financial p...
 
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.pptUnit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
Unit-III-ELECTROCHEMICAL STORAGE DEVICES.ppt
 
Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...
 
New techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdfNew techniques for characterising damage in rock slopes.pdf
New techniques for characterising damage in rock slopes.pdf
 
Properties Railway Sleepers and Test.pptx
Properties Railway Sleepers and Test.pptxProperties Railway Sleepers and Test.pptx
Properties Railway Sleepers and Test.pptx
 
132/33KV substation case study Presentation
132/33KV substation case study Presentation132/33KV substation case study Presentation
132/33KV substation case study Presentation
 
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
 
ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024
 
basic-wireline-operations-course-mahmoud-f-radwan.pdf
basic-wireline-operations-course-mahmoud-f-radwan.pdfbasic-wireline-operations-course-mahmoud-f-radwan.pdf
basic-wireline-operations-course-mahmoud-f-radwan.pdf
 

Types End-to-End @ samsara

  • 1. Types End-to-end More Features And Fewer Bugs with GraphQL
  • 7.
  • 8. mo' features, mo' problems.
  • 9. GraphQL Schema type Device { name: string!; id: number!; currentDriver: Driver; locations: [Location!]!; // ... } type Root { device(id: number!): Device; }
  • 10. mo' features, mo' problems. (mo' static types)
  • 12. safety static verification at compile time and deployment editor tooling autocomplete, go to definition, type hints
  • 14. a simple example # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; }
  • 15. a simple example # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 16. plain old javascript const DeviceNameComponent = props => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL(DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }));
  • 17. oh no const DeviceNameComponent = props => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL(DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }));
  • 18. oh no const DeviceNameComponent = props => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL(DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }));
  • 19. oh no const DeviceNameComponent = props => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL(DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }));
  • 20. oh no const DeviceNameComponent = props => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL(DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }));
  • 22. typing it all out (by hand) # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 23. typing it all out const DeviceNameComponent = props => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL(DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }));
  • 24. typing it all out (with typescript!) const DeviceNameComponent = (props: Props) => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryInputVariables> (DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }) );
  • 25. typing it all out with typescript! const DeviceNameComponent = (props: Props) => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables> (DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }) );
  • 26. typing it all out with typescript! const DeviceNameComponent = (props: Props) => { return <div>Name: {props.graphqlValue.device.fullName}</div>; } export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables> (DeviceNameComponent, () => ({ query: ..., variables: { deviceId: 202152006793, }, }) );
  • 27. this works pretty well, but...
  • 28. a simple example # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 29. uh oh query VehicleInfo($deviceId: int64, $durationMs: int64!, $endMs: int64) { device(id: $deviceId) { id name currentDriver { id name } setPoint: objectStat(statType: SET_POINT) { intValue } vehicleActivityReport(duration: $durationMs, endTime: $endMs) { tripEntries { start { address } end { address } } } ...DashcamLatestImage ...CurrentStats } }
  • 30. uh oh uh oh query VehicleInfo($deviceId: int64, $durationMs: int64!, $endMs: int64) { device(id: $deviceId) { id name currentDriver { id name } setPoint: objectStat(statType: SET_POINT) { intValue } vehicleActivityReport(duration: $durationMs, endTime: $endMs) { tripEntries { start { address } end { address } } } ...DashcamLatestImage ...CurrentStats } } type VehicleInfoQueryVariables = { deviceId: number, durationMs: number, endM?: number, }; type VehicleInfoQueryResult = { device: { id: number, name: string, setPoint: Array<number>, vehicleActivityReport: { start: { address: string, }, end: { address: string, }, } >, }, lastDashcamEvent: { reportType: number, triggerTime: number, urls: { still: string, }, } | null, },
  • 31. hmm... # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } } // generated_types.d.ts type DeviceNameQueryInputVariables = { id: number; } type DeviceNameQuery = { device: { name: string; } }
  • 32. the graphql schema and typescript types can be mapped 1:1
  • 35. how does codegen work? # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 36. how does codegen work? # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 37. how does codegen work? # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } } // generated_types.d.ts type DeviceNameQueryInputVariables = { id: number; }
  • 38. how does codegen work? # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 39. how does codegen work? # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 40. how does codegen work? # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } }
  • 41. how does codegen work? # server_schema.graphql: type Device { name: string!; } type Root { device(id: number!): Device; } # device_name_query.graphql: query DeviceName($id: number!) { device(id: $id) { name } } // generated_types.d.ts type DeviceNameQuery = { device: { name: string; } }
  • 42. $ ts-node codegen.ts > schema.d.ts
  • 43. typing without typing const DeviceNameComponent = (props: Props) => { return <div>Name: {props.graphqlValue.device.name}</div>; } export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables> (DeviceNameComponent, () => ({ query: ..., variables: { id: 202152006793, }, }) );
  • 44. typing without typing import { DeviceNameQuery, DeviceNameQueryVariables } from "./generated_types"; const DeviceNameComponent = (props: Props) => { return <div>Name: {props.graphqlValue.device.name}</div>; } export default connectGraphQL<Props, DeviceNameQuery, DeviceNameQueryVariables> (DeviceNameComponent, () => ({ query: ..., variables: { id: 202152006793, }, }) );
  • 47. can we go further?
  • 48. can we go further?
  • 49. golang types # graphqlschema/device.go type Device struct { Id int64 Name string OrganizationId int64 // ... } type deviceArgs struct { Id int64 } root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) { user, err := db.Device.Get(...) return user, err })
  • 50. golang types # graphqlschema/device.go type Device struct { Id int64 Name string OrganizationId int64 // ... } type deviceArgs struct { Id int64 } root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) { user, err := db.Device.Get(...) return user, err }) # server_schema.graphql: type Device { name: string!; id: number; // ... } type Root { device(id: number!): Device; }
  • 51. the go type definitions and graphql schema can also be mapped 1:1
  • 52. ✨ thunder + reflection ✨
  • 53. golang types # graphqlschema/device.go type Device struct { Id int64 Name string OrganizationId int64 // ... } type deviceArgs struct { Id int64 } root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) { user, err := db.Device.Get(...) return user, err })
  • 54. golang types # graphqlschema/device.go type Device struct { Id int64 Name string OrganizationId int64 // ... } type deviceArgs struct { Id int64 } root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) { user, err := db.Device.Get(...) return user, err }) # server_schema.graphql: type Root { device(id: number!): Device; }
  • 55. golang types # graphqlschema/device.go type Device struct { Id int64 Name string OrganizationId int64 // ... } type deviceArgs struct { Id int64 } root.FieldFunc("device", func(ctx context.Context, args userArgs) (*Device, error) { user, err := db.Device.Get(...) return user, err }) # server_schema.graphql: type Device { name: string!; id: number; // ... }
  • 56. $ go run schema_generator.go > schema.graphql
  • 59. can we go further?
  • 60. can we go further?
  • 61. can we go further?
  • 62. protobuf go generation message TemperatureStat { int64 time = 1; double double_value = 3; }
  • 63. surprise! protobufs and go types can also, also be mapped 1:1
  • 65. protobuf go generation message TemperatureStat { int64 time = 1; double double_value = 3; }
  • 66. protobuf go generation message TemperatureStat { int64 time = 1; double double_value = 3; } type TemperatureStat struct { Time int64 DoubleValue float64 }
  • 67. $ protoc-gen-go > stat.pb.go
  • 70. type once, benefit everywhere. schemas and typings can never be out of sync.
  • 71. type once, benefit everywhere. autocomplete, go to def, outlines in your {.pb.go, .go, .graphql, .tsx}.
  • 72. type once, benefit everywhere. a type can travel from the hardware device to the web application.
  • 73. type once, benefit everywhere. available in an open source repository near you.
  • 74. type once, benefit everywhere. a powerful default. let the computer do the busy work for you.
  • 77. the tools are there! we just need to add a little grease.
  • 78. Never Type Anything Type TypeScript from GraphQL Type GraphQL from Go Type Go from Protobufs
  • 79. Type mapping is not always 1:1 ● Union Types (supported ts, graphql, but not go) ● Enums Types (supported in ts, graphql, but not go) ● Number Types (float64 only in javascript) ○ A bit of a type safety problem, but we haven't hit the bounds of float64 in production yet. ○ We could also have a different over the wire representation for dealing with this ● Nullable Types (pointer types are not quite option types) ○ Error | Null | Value vs. (Null | Value, Error)
  • 81. what do we get out of static type checking? ● Type Safety ● Deployment Safety ● Autocomplete, Go to Definition
  • 84. protobufs cont. (grpc systems behind graphql) rpc UpdateDriverSafetyEvents(UpdateDriverSafetyEventsRequest) returns (UpdateDriverSafetyEventsResponse) {} message DriverSafetyEventsRequest { int64 org_id = 1; repeated int64 device_ids = 2; int64 end_ms = 3; int64 start_ms = 4; } message DriverSafetyEvent { int64 device_id = 1; int64 harsh_event_ms = 2; HarshEvent harsh_event = 3; SafetyEventMetadataInboxState state = 4; } message DriverSafetyEventsRequest { int64 org_id = 1; repeated int64 device_ids = 2; int64 end_ms = 3;
  • 85. can we make this nicer?
  • 86. Demands: more codegen ● What else can we do? ● extracting golang comments at compile time ● apollo-codegen with a go compilation target (i.e. for a graphql consumer api service)
  • 87. Demands: Better Type Interoperability ● Steps for code generation are still a little hard ● Need better ways of providing types across the board ● Providing Types: typescript/#3136

Editor's Notes

  1. i am stephen frontend infra, including graphql
  2. We really view ourselves as a platform company - there are so many applications we can build on top of our hardware and software.
  3. So behind the scenes, what does this look like? We have our gateway device that can run go programs, It sends its data over to our go-based backend services, and those services are abstracted behind our GraphQL layer, which ends up serving our react web application, and react native mobile application, written in typescript
  4. GraphQL becomes our one true language from the backend
  5. Going back a little, we have a lot of different types of data flowing through the system that need to make it on to the page. A vehicle might have a dash cam installed taking videos, it might have a temperature sensor for monitoring food shipments, it might be taking gps speed measurements - the relationships between all of this can get complicated And that's where we think a type system has a really big impact
  6. Find (some) bugs without executing the program Matters when you write a ton of features, lots of people doing everything (x functional teams) We have lots of teams working on features, some that overlap. Maintaining consistency is important.
  7. Find (some) bugs without executing the program Matters when you write a ton of features, lots of people doing everything (x functional teams) We have lots of teams working on features, some that overlap. Maintaining consistency is important.
  8. Find (some) bugs without executing the program Matters when you write a ton of features, lots of people doing everything (x functional teams) We have lots of teams working on features, some that overlap. Maintaining consistency is important.
  9. Mentioned earlier that we use GraphQL and TypeScript Let's look at an example where this might be useful
  10. What's wrong? (It's hard to tell)
  11. query inputs are checked
  12. query inputs are checked
  13. query inputs are checked
  14. query inputs are checked
  15. query inputs are checked
  16. query inputs are checked
  17. query inputs are checked
  18. query inputs are checked
  19. query inputs are checked
  20. but it's kind of disatisfying
  21. query inputs are checked
  22. Find (some) bugs without executing the program Matters when you write a ton of features, lots of people doing everything (x functional teams) We have lots of teams working on features, some that overlap. Maintaining consistency is important.
  23. Read the code for this Draw a diagram for inputs/outputs "mapping" type systems
  24. run it on the command line
  25. reflection: program reflecting, asking about itself
  26. query inputs are checked
  27. Now we know that our graphql service and our frontend will always agree, with no manual steps required Autocomplete, compile time checking in the frontend
  28. Highlight GraphQL service / web client as type safe Where does the graphql schema come from?
  29. Find (some) bugs without executing the program Matters when you write a ton of features, lots of people doing everything (x functional teams) We have lots of teams working on features, some that overlap. Maintaining consistency is important.
  30. Highlight GraphQL service / web client as type safe Where does the graphql schema come from?
  31. reflection: program reflecting, asking about itself
  32. reflection: program reflecting, asking about itself
  33. Highlight GraphQL service / web client as type safe Where does the graphql schema come from?
  34. Highlight GraphQL service / web client / Backend as type safe
  35. Find (some) bugs without executing the program Matters when you write a ton of features, lots of people doing everything (x functional teams) We have lots of teams working on features, some that overlap. Maintaining consistency is important.
  36. Highlight GraphQL service / web client / Backend as type safe
  37. Highlight GraphQL service / web client / Backend as type safe Show some code snippets (which are handwritten? which are generatede)
  38. Find (some) bugs without executing the program Matters when you write a ton of features, lots of people doing everything (x functional teams) We have lots of teams working on features, some that overlap. Maintaining consistency is important.
  39. reflection: program reflecting, asking about itself
  40. reflection: program reflecting, asking about itself
  41. Highlight GraphQL service / web client / Backend as type safe Show some code snippets (which are handwritten? which are generatede)
  42. Single shared type defintion, for any piece of data Generate defintions, so developers don't need to
  43. entire class of problem
  44. not novel - everything is available in open source (protobufs, thunder, apollo-codegen, typescript) we encourage you to try this out. we look forward to ???
  45. really powerful default when working across the stack we encourage you to try this out. there's a little grease involved,
  46. reflection: program reflecting, asking about itself really powerful default individual steps not really novel apollo-codegen star count apollo-client example documentation
  47. It's still possible to ship buggy changes to business logic But we've eliminated an entire source of potential errors from production
  48. It's still possible to ship buggy changes to business logic But we've eliminated an entire source of potential errors from production