End-to-end

Type-Safe
GraphQL
Apps

Carlos Rufo / 19-02-2019 / #2 Sevilla TypeScript Meetup

๐Ÿ‘‹ , I'm Carlos!

OSS Developer

@swcarlosrj

Agenda

  • Intro to GraphQL๐Ÿ’ก

  • TypeScript ๐Ÿ’™ GraphQL

  • ๐Ÿš€ Live Coding

  • ๐Ÿ™‹โ€โ™€๏ธ Q&A ๐Ÿ™‹โ€โ™‚๏ธ

Intro to
GraphQL๐Ÿ’ก

Why ๐Ÿค”

  • Efficiency

  • Type System

  • Documentation

  • Versioning

  • Tooling

Efficiency

  • Overfetching

  • Underfecthing

โš ๏ธ Common issues in current APIs

Overfetching

Ask for what you need,
get exactly that ๐ŸŽ†

"Fetch more data
that the client
actually needs"

Overfetching

Save resources,
respond faster โšก๏ธ

Efficiency

๐Ÿคฉ Desktop ~ 100% ย 

๐Ÿ˜ง Mobile ~ 60%

๐Ÿ˜ฑ Watch ~ 20%

Reusability

๐Ÿ˜ƒ /desktop/launches

๐Ÿคจ /mobile/launches

๐Ÿ˜ค /watch/launches

Underfetching

Ask for nested resources,
get all of that ๐ŸŽ‡

"Fetch not enough data that the client
actually needs"

Underfetching

Handle data
in your ๐Ÿ“ฑ,
instead over the ๐ŸŒ!

REST

๐Ÿคฉ /launches - 1 HTTP/DB

๐Ÿ˜ง /rocket/:id - 'N' HTTP/DB
๐Ÿ˜ญ Client parse functions

GraphQL

๐Ÿ˜ƒ /graphql - 1 HTTP/'N' DB

๐Ÿ˜Ž No client parse functions

Type System

Docs

  • Auto-Generated

  • Typed

  • Up-to-Date

ย 

It's just ๐Ÿ”ฅ

Versioning

Tooling

Move faster with
powerful dev tools ๐Ÿ•น

  • GraphiQL

  • Auto-Gen Types

  • IDEs extensions

How ๐Ÿง

  • Entry points

  • TypeDefs

  • Resolvers

  • Context

  • Servers

Entry points

  • Query (Get data)

  • Mutation (Modify data)

  • Subscription (Subscribe to data)

TypeDefs

type Query {
  launches: [Launch]
  launch(id: ID!): Launch
}
type Rocket {
  id: ID!
  name: String
}
type Launch {
  id: ID!
  name: String
  details: String
  image: String
  rocket: Rocket
  ship: Ship
}
type Ship {
  id: ID!
  name: String
  port: String
  image: String
}

Entry points

Type

Sub Types

Resolvers

Query: {
    launches: async (obj, args, context) => {
        const data = await context.db
          .collection('launch')
          .toArray();
    
        return data;
    },
    launch: async (obj, { id }, context) => {
        const [data] = await context.db
          .collection('launch')
          .find({ id })
          .toArray();
    
        return data;
    },
}

Context

DRY โ™ป๏ธ

import db from '../db';
import { find, limit, offset, order, sort } from '../utils';

const context = {
    db,
    find,
    limit,
    offset,
    order,
    sort
};

export default context;

Servers

const server = new GraphQLServer({
  typeDefs,
  resolvers,
  context
});

server.listen()

What ๐Ÿคฉ

  • Specification

  • Query Language

  • Features

  • History

  • Learn

Specification

It's not a library,
nor a framework

Is a language-agnostic
specification for your API!

Query Language

It's not a library,
nor a framework

Is a Graph QL
for your API!

Features

  • Strongly Typed

  • Introspection

  • Queries, Mutations & Subscriptions

  • Transport agnostic

  • Client-specified response shape

  • Efficient

History

  • Several clients support need

  • Rethink app data-fetching

  • "Write once, run anywhere"

Learn

Confs

GQL Asia ๐Ÿ‡ฎ๐Ÿ‡ณ Apr 12-13ย 

GQL Conf ๐Ÿ‡ฉ๐Ÿ‡ช Jun 20-21
GQL Summit ๐Ÿ‡บ๐Ÿ‡ธ Oct 29-31

Tutorials

How To GraphQL

Newsletters

GraphQL Weekly

๐Ÿ”œ Open GraphQL

Blogs

Open GraphQL

TypeScript
๐Ÿ’™
GraphQL

Let's recap about typed languages

Static ๐Ÿ‘‰ Compile-Time ๐Ÿ‘‰ Java
Dynamic ๐Ÿ‘‰ Run-Time ๐Ÿ‘‰ JavaScript

JavaScriptย ๐Ÿ‘ˆย No types ๐Ÿ‘ˆ Weakly
ย TypeScript ๐Ÿ‘ˆย Types ๐Ÿ‘ˆย Strongly

Type-Safe Apps

๐Ÿ’ช Typed BE
โž•
๐Ÿ’ช Typed FE
โž•

BE Types โœ… FE Types

Single Source of Truth

Auto-generateย types
based on your
GraphQL implementation

Implementations

Schema First
๐Ÿ‘ Fully client-focused design
๐Ÿ‘Ž Code reuse, Type safety

๐Ÿ›  Apollo Server, GraphQL Yoga

Resolver First
๐Ÿ‘ Can be type-safe
๐Ÿ‘Ž MVC confusion, less client focus
๐Ÿ›  graphql.js

Model First
๐Ÿ‘ Code reuse, T
ype safety
๐Ÿ‘Ž Most "distance" between code & schema
๐Ÿ› 
GraphQL Nexus, TypeGraphQL

Schema First

type Query {
  launches: [Launch]
  launch(id: ID!): Launch
}

type Launch {
  id: ID!
  name: String
  details: String
  image: String
  rocket: Rocket
  ship: Ship
}
type Rocket {
  id: ID!
  name: String
}
type Ship {
  id: ID!
  name: String
  port: String
  image: String
}
Query: {
    launches: async (obj, args, context) => {
        const data = await context.db
          .collection('launch')
          .toArray();
    
        return data;
    },
    launch: async (obj, { id }, context) => {
        const [data] = await context.db
          .collection('launch')
          .find({ id })
          .toArray();
    
        return data;
    },
}

Introspection

Explore the GraphQL Schema
& take advantage of it predictability โœจ

Type Generators

Frontend

Apollo Codegen

Auto-generateย types
based on your
GraphQL implementation

๐Ÿš€ Live
Coding

Design

Let's make
this work out ๐Ÿ’ช

GraphQL
๐Ÿ’œ
REST

๐Ÿ™‹โ€โ™€๏ธ Q&A ๐Ÿ™‹โ€โ™‚๏ธ

Thanks for coming ๐Ÿ˜„

Meetup #2: TypeScript, GraphQL y React
Sevilla TypeScript Meetup

See you in the next one?

End-to-end Type-Safe GraphQL Apps - Sevilla TypeScript

By Carlos Rufo

End-to-end Type-Safe GraphQL Apps - Sevilla TypeScript

  • 493