GraphQL

https://goo.gl/xwJSxY

About me

  • Formado em Sistemas de Informação
  • Mantenedor do ng-cordova-oauth, Ionic Flat Colors
  • Fullstack no Saúde Vianet
  • Software Engineer Jusbrasil
  • Software Engineer CW (Mobile)
  • Frontend Engineer Xing.com
  • Guitarrista e baixista nas horas vagas

@matheusrocha89

@matheusrocha

React Salvador: Matheus (Brian)

Antes do GraphQL

MVC

Cresce o mercado mobile.

E agora?

REST

fetch('https://api.domain.com/v1/users/123');
...

{
    ...,
    data: {
        id: 123,
        firstName: '...',
        lastName: '...',
        email: '...',
        ...,
    }
}

E se precisarmos de dados mais complexos?

Criamos mais endpoints

  • v1/users/123/friends
  • v1/users/123/posts
  • v1/users/123/last-posts
  • v1/users/123/friends/liked-pages
  • v1/users/123/friends/last-liked-pages
  • v1/users/123/friends/last-liked-pages/last-posts
  • v1/users/123/friends/last-liked-pages/posts-friends-liked
  • v1/users/123/friends/last-photos-and-pages-liked
  • v1/users/123/i-dont-have-any-idea-what-the-hell-is-this-anymore

Retorna mais dados do que você realmente precisa

Agora temos um sério problema

Surge o GraphQL

2012

GraphQL é criado e usado internamente pelo Facebook

2015

GraphQL é liberado Open Source pelo Facebook

Mas o que era esse tal de GraphQL

"GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data."

Quais as vantagens disso?

GraphQL

Client

Backend

GraphQL

Client

Backend

Backend

Novo mindset

Conceitos

Tipagem

Tipos

  • Int
  • Float
  • String
  • Boolean
  • ID
  • Enum

Mas...

Nada impede de você criar os seus próprios tipos de dados

type Character {
  name: String!
  appearsIn: [Episode]!
}

Tipos Query e Mutation

Query

Mutation

type Query {
  posts: [Post]
  author(id: Int!): Author
}
type Mutation {
  upvotePost(postId: Int!): Post
}

Interfaces

interface Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}

type Human implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  starships: [Starship]
  totalCredits: Int
}

type Droid implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  primaryFunction: String
}

// Query

query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
  }
}

Fragments

{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}

Subscription

// Server
type Subscription {
  postAdded: Post
}


// Client

subscription {
  postAdded {
    id
    title
    content
  }
}

Schema

  type Author {
    id: Int!
    firstName: String
    lastName: String
    posts: [Post] # the list of Posts by this author
  }

  type Post {
    id: Int!
    title: String
    author: Author
    votes: Int
  }

  # the schema allows the following query:
  type Query {
    posts: [Post]
    author(id: Int!): Author
  }

  # this schema allows the following mutation:
  type Mutation {
    upvotePost (
      postId: Int!
    ): Post
  }

OK! Eu defino meu grafo mas... como ele sabe buscar esses dados?

Resolvers

Parâmetros do Resolver

  • parent / root
  • args
  • context
  • info
import { find, filter } from 'lodash';

// example data
const authors = [
  { id: 1, firstName: 'Tom', lastName: 'Coleman' },
  { id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
];
const posts = [
  { id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
  { id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
];

const resolvers = {
  Query: {
    posts: () => posts,
    author: (_, { id }) => find(authors, { id: id }),
  },
  Mutation: {
    upvotePost: (_, { postId }) => {
      const post = find(posts, { id: postId });
      if (!post) {
        throw new Error(`Couldn't find post with id ${postId}`);
      }
      post.votes += 1;
      return post;
    },
  },
  Author: {
    posts: (author) => filter(posts, { authorId: author.id }),
  },
  Post: {
    author: (post) => find(authors, { id: post.authorId }),
  },
};

Mas...

Além do que eu falei

  • Dataloader (batching, caching).
  • Autorização.
  • Metadados que podem ser usados.
  • Liberdade para criar paginação
  • Validação

Não se esqueça: o facebook usa GraphQL

Ele veio preparado

Vantagens do GraphQL sobre o REST

Sem over-under fetching

Evolução mais rápida do produto

Onde aprender mais

  • http://graphql.org/
  • https://www.howtographql.com/
  • https://services.github.com/on-demand/graphql/
  • https://github.com/blog/2412-learn-graphql-with-github

Ferramentas / Links interessantes

GraphiQL

http://graphql.org/swapi-graphql/

https://developer.github.com/v4/explorer/

https://github.com/matheusrocha89/graphql-with-firestore-example

Graphile - https://www.graphile.org/

Servers GraphQL

NodeJS, PHP, Ruby, Go, Java, Elixir, Erlang, Groovy, Scala, Clojure, C#, Python...

Clients GraphQL

NodeJS, Javascript, Go, C#, Java (Android), Swift/Objective-C, Python.

Quem está utilizando?

E muito mais

Exemplo

Obrigado!!

GraphQL

By Matheus Cruz Rocha

GraphQL

Apresentação sobre GraphQL

  • 1,730