introduction to TYPESCRIPT
IMPROVING THE JS CODE WE WRITE
Type Systems
Potential solutions to the JS problem
AGENDA
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
JAvascript's type system
WHAT'S A TYPE?
Numbers -
Strings -
They define the operations and the meaning of the data
(x+y, a-b, s*t )
(x+y, a<b, s>t )
TYPES IN JS
boolean
typeof x
string
object
undefined
symbol
function
TYPE ERRORS in js
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
WHY PROBLEMATIC?
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
WHY PROBLEMATIC?
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
JS TRies to avoid errors
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
rest API - QUERY PARAMETERS
/postsTitle
/postsTitleAndAuthor
/posts
/postsTitleAuthorAndContent
/postsTitleAuthorContentAndImages
/postsTitleAuthorContentAndImagesAndComments
REST API - CUSTOM ENDPOINTS
BLOG API - hypermedia for nested queries
IS THERE A ANOTHER (BETTER) WAY TO AVOID THE OVERFETCHING OR UNDERFETCHING OF DATA?
tools for typechecking
LINTERS
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
CUSTOM TYPECHECK
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
PROPTYPES
graphql operations
GET
QUERY
POST
PUT
PATCH
DELETE
REST
GRAPHQL
MUTATION
WEBSOCKSETS
SUBSCRIPTION
graphql QUERY
GET /posts?include=title,author
Type of operation
"Endpoint"
Fields
graphql QUERY
GET /posts?include=title,author
Query
Response
graphql - QUERY
GET /posts/<:id>
Query
Response
graphql - nested QUERY
/posts?include=title,author.firstName, author.lastName, author.avatar
GET
graphql - DEEPLY nested QUERY
graphql - MUTATION
POST /author/{data}
typescript
TYPESCRIPT
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
client query example
client mutation example
graphql server-side
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
graphql server side - node.js example
Schema
Resolvers*
* Parts of code have been stripped for brevity
graphql server side - node.js example
App.js*
* Parts of code have been stripped for brevity
GRAPHIQL -SELF DOCUMENTING API BROWSER
GRAPHIQL -SELF DOCUMENTING API BROWSER
graphql through the lens
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
N+1 pROBLEM
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.
- BULK REST
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
A WHOLE LOT MORE USERS
summary
No overfetching or underfetching of data - Clients dictate what they need
WHERE IT SHINES
- JavaScript doesn't give us enough type errors
- Static type checking can help!
- Working with types will help you think better
- You might want a 100% type system instead of 80%
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
DISADVANTAGES
FAQ
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
Useful links
Playground
General info
Blogs from adopters of GraphQL
Into to TypeScript
By Elom T
Into to TypeScript
Make JS even better
- 87