End-to-end type safety with GraphQL, Apollo, TypeScript, and React
 

+

+

+

Buzzwords!

What are we really talking about?

Leveraging a GraphQL schema as a source of truth can elevate confidence, improve quality, and hyper charge velocity 

Mike DeWitt

Director of Engineering, First Dollar

AKA: It's a bank account

What is First Dollar?

State of JS: 2020

https://2020.stateofjs.com/en-US/

State of JS: 2020

https://2020.stateofjs.com/en-US/

State of JS: 2020

https://2020.stateofjs.com/en-US/

GraphQL

  • Describe your data (Schema)
  • Query, mutate, or subscribe
  • Ask only for what you need

Simple GraphQL Schema

  type Query {
    books: [Book!]!
  }

  type Mutation {
    addBookToCart(bookId: String!): Book!
  }

  type Book {
    id: String!
    inStock: Boolean!
    title: String!
    author: String!
    thumbnail: String!
    description: String!
    price: String!
  }

TypeScript

  • Brings static typing to JavaScript
  • Provides compile time errors instead of runtime errors
  • TypeScript plays great with React

Book Type Safety

  type Book = {
    id: string
    inStock: boolean
    title: string
    author: string
    thumbnail: string
    description: string
    price: string
  }
  
  const myBook: Book = {
    id: "fk903",
    title: "Untamed",
    price: "$25.99",
    inStock: false,
    author: "Glennon Doyle",
    description: "description",
    thumbnail: "https://pic.com",
  }
  
  // Valid
  myBook.title.toLowerCase()
  
  // TS Failure: Property 'salePrice' does not exist on type 'Book'
  myBook.salePrice.toLowerCase()
  
  // TS Failure: Property 'toLowerCase' does not exist on type 'boolean'.
  myBook.inStock.toLowerCase()

We have to define a schema for GraphQL, and we want type safety on the frontend...

https://graphql-code-generator.com/

GraphQL Code Generator

  • Install and Configure
  • NPM Scripts
  • Import types to components

Demo #1

Thumbnail is not required, and we forgot to add price

Demo #2

We should probably write tests

currentUserProfile

  • Called in 14 components
  • Mocked in 8 tests

First Dollar React App

Other facts

  • 37 total queries, 36 mutations
  • We have a small/medium sized app
  query AccountTransfers($fromDate: String, $toDate: String, $page: PageInput) {
    accountTransfers(fromDate: $fromDate, toDate: $toDate, page: $page) {
      transfers {
        node {
          id
          createdAt
          linkedBankAccountId
          direction
          amount
          amountCurrency
          amountForDisplay
          note
          contributionType
          contributionYear
          withdrawalCategoryCode
          withdrawalExpenseDate
          withdrawalReceipts {
            bucket
            fullPath
          }
          status
          effectiveDate
          errorCode
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }

Demo #3

Better feedback eslint-plugin-graphql

Is your client safe to ship?

  • When you deploy the production GQL server, export the schema and keep in cloud storage
  • When deploying client, download latest production schema and eslint it
  • This should prevent you from ever shipping clients that are querying things on your dev server that haven't been released to prod

Worth mentioning... With a Node.js backend, this same tooling can be applied, in reverse!

In closing...

Thanks! Questions?

Demo

Title Text

  • Bullet One
  • Bullet Two
  • Bullet Three

Type safety w/ GraphQL and React

By Michael DeWitt

Type safety w/ GraphQL and React

  • 463