Type Systems
Potential solutions to the JS problem
JavaScript's Type System
The problem
Type Script
Client and Server side code
GraphQL through the lens.
How a few companies leverage GraphQL
Summary
Takeaways, Strenghth & Weakeness
Numbers -
Strings -
They define the operations and the meaning of the data
(x+y, a-b, s*t )
(x+y, a<b, s>t )
boolean
typeof x
string
object
undefined
symbol
function
cannot read property of undefined
x is not a function
The TypeError represents an error when an operation could not be performed
Typerrors depend on runtime for errors
var x = 10
var y = x.parent
// ^ the real error is thinking `x` has a `.parent`
return y.name
// ^ but JS gives us the error here
Looks like its one line off but think of production codebase where its many files call stacks away
function doSomething(m) {
// numbers don't have a count
if (m.count > 2) {
return "large"
} else {
return "small"
}
}
// but js will happily return "small" here
doSomething(5)
Ask what errors we will get from this - None
2/'' === Infinity
2 + {} === '2[object Object]'
2 + 'phone' -> NaN
alert(1, 2, 3, 4, 5)
But it doesnt always work out
LET'S TRY TO SLIM DOWN THE DATA FROM SERVER
/posts?include=title,author
/postsTitle
/postsTitleAndAuthor
/posts
/postsTitleAuthorAndContent
/postsTitleAuthorContentAndImages
/postsTitleAuthorContentAndImagesAndComments
IS THERE A ANOTHER (BETTER) WAY TO AVOID THE OVERFETCHING OR UNDERFETCHING OF DATA?
GraphQL is a query language for your API
GraphQL queries are all POST made to a single endpoint
Open sourced by Facebook in 2015
Gives clients power to ask for exactly what they need
No versioning - single evolving version
function greet(greeting, months, age) {
if (arguments.length !== 3)
throw new Error('must be called with 3 arguments')
}
function greet(greeting, months, age) {
if (arguments.length !== 3)
throw new Error('must be called with 3 arguments')
if (typeof greeting !== 'string')
throw new Error('greeting must be a string')
if (!Array.isArray(months))
throw new Error('months must be an array')
if (typeof age !== 'number')
throw new Error('age must be a number')
}
It get's messy
GET
QUERY
POST
PUT
PATCH
DELETE
REST
GRAPHQL
MUTATION
WEBSOCKSETS
SUBSCRIPTION
GET /posts?include=title,author
Type of operation
"Endpoint"
Fields
GET /posts?include=title,author
Query
Response
GET /posts/<:id>
Query
Response
/posts?include=title,author.firstName, author.lastName, author.avatar
GET
POST /author/{data}
function greet(greeting, months, age) {
if (arguments.length !== 3)
throw new Error('must be called with 3 arguments')
if (typeof greeting !== 'string')
throw new Error('greeting must be a string')
if (!Array.isArray(months))
throw new Error('months must be an array')
if (typeof age !== 'number')
throw new Error('age must be a number')
}
function greet(greeting: string,
months: Array<string>,
age: number) {
}
runs ahea of time, litttle boiler plate, applies to fns variables, open source
GraphQL server is made of two main parts Schema and Resovlers
Schema - Define the type of data of endpoints and serve as validation against queries
Resolvers - Functions that contain logic to implement the API. Each field type has one
Several GraphQL server-side libraries to connect schemas and resolvers
Graphql-java
Schema
Resolvers*
* Parts of code have been stripped for brevity
App.js*
* Parts of code have been stripped for brevity
They discovered GraphQL while developing their new mobile app in 2016
Their motivation for adoption was to reduce round trips to server and to customize the data they received
They used GraphQL Ruby implementation since their backend is in Ruby
Biggest issues faced was the "n+1 problem"
GraphQL API is public for 3rd party developers to integrate with their platform
GraphQL reduced bandwidth of app users with limited data plans
Assuming the author field is from an Author table in the DB, we are going to query our DB for as many posts present
Shopify and others have leveraged DataLoader to implement similar for other languages
GraphQL created a DataLoader utility to batch requests for JS-based apps
Initially utilized REST for it's design principles that are widely understood
Their Checkout API round trip costs was causing slower rendering time for users
Developers were constantly torn with the decision of creating new endpoints vs overloading an existing end point
Created Bulk REST as an alternative for clients to control size and shape of data but it didn't gain traction
UI Developers were spending only 1/3 of time building UI. Rest of time was spent filtering, mapping over data and orchestration API calls
GraphQL provided performance gains, developer productivity and allowed API developers to know what fields clients were using.
Request
Response
Started with TweetDeck and later rolled it into their iOS and Android apps
Utilized GraphQL for similar reasons to Shopify and PayPal
Hard to track exceptions per query as GraphQL requests always returned 200 status codes.
Additionally, they use GraphQL subscription to enable clients to subscribe to topics and receive periodic payloads
To safegaurd against extremely expensive queries, the set a limit to depth of each query
"Our responses simultaneously sent too much data and didn’t include data that consumers needed."
They began the migration by testing the implementation of a small feature: emoji reactions on comments
GitHub engineers likened their GraphQL adoption to switching from XML to JSON.
The REST API was responsible for over 60% of the requests made to our database
Bulk of 60% requests were from hypermedia navigation links which also caused bloating of responses
No overfetching or underfetching of data - Clients dictate what they need
Knowledge of structure of data in advance to maximize usage
Custom error handling - Queries return a status of 200 for partially successful requests
Identifying and resolving the "n+1 problem"
Caching- Lack of built in caching. REST uses standard HTTP cache systems because of multiple endpoints and consistent structure of data
Tooling - Not as many commercial products for monitoring/alerting/logging of API
Is GraphQL built on top of REST?
No, it's a query language for your API. it send requests over HTTP like you can do with REST.
Why do we always send a POST request with GraphQL?
This is because with GraphQL, we always send a body with our request. A GET request does not support a body hence we wouldn't be able to make a query
How can I use an existing REST API with GraphQL?
Yes. You can achieve this by having a thin client and server-side REST wrapper. Several examples available online
How does caching work with GraphQL?
Though caching is not directly supported out of the box, several clients like Apollo-client do have caching mechanisms
How is the filtering of data done on the backend in GraphQL?
GraphQL server libraries bind your schema and resolvers together. With this binding, filtering is handled for you.
Is GraphQL only supported in Javascript?
No. There are several implementations for all popular backend languages - Java, Go, Ruby, Scala, Clojure, .NET, PHP, Python.. etc
Playground
General info
Blogs from adopters of GraphQL