SlideShare a Scribd company logo
1 of 96
Download to read offline
What/how to do with GraphQL?
Valentyn Ostakh
#27
query {
me {
firstName
lastName
company
position
socialLinks {
name
url
}
}
}
{
"data": {
"me": {
"firstName": "Valentyn",
"lastName": "Ostakh",
"company": "RubyGarage",
"position": "Ruby/JS developer",
"socialLinks": [
{
"name": "facebook",
"url": "https://facebook.com/valikos"
},
{
"name": "twitter",
"url": "https://twitter.com/valikos_ost"
},
{
"name": "github",
"url": "https://github.com/valikos"
}
]
}
}
}
Agenda
• Introduction into GraphQL

• GraphQL SDL(Schema Definition Language)

• GraphQL Execution

• Pitfalls
What is
GraphQL?
🤔
What is GraphQL?
• A query language for API

• A type system of defined data

• A platform of both backend + frontend applications
More About GraphQL
• GraphQL was developed internally by Facebook in 2012 before being
publicly released in 2015

• The idea of GraphQL became from the frontend team

• GraphQL services can be written in any language

• GraphQL is transport-agnostic

• GraphQL represents data in graphs
GraphQL SDL
What to do with GraphQL?
🗺
GraphQL SDL
GraphQL schema is at the center of any GraphQL server
implementation.

GraphQL schema describes the functionality available to the
clients who connect to it
GraphQL SDL
• Schema

• Object Types

• Fields

• Scalars

• Enums

• Lists

• Non-Null
• Directives

• Aliases

• Interfaces

• Unions

• Fragments

• Input Objects
Object Type
GraphQL Object Type
{
"data": {
"character": {
"firstName": "Peter",
"lastName": "Griffin",
"friends": [
{
"firstName": "Brian",
"lastName": null
},
{
"firstName": "Homer",
"lastName": "Simpson"
}
]
}
}
}
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL Object Type
{
"data": {
"character": {
"firstName": "Peter",
"lastName": "Griffin",
"friends": [
{
"firstName": "Brian",
"lastName": null
},
{
"firstName": "Homer",
"lastName": "Simpson"
}
]
}
}
}
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL Object Type
type Character {
firstName: String!
lastName: String
friends: [Character!]
}
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true
field :friends, [Types::CharacterType], null: true
end
end
Fields
GraphQL Fields
type Character {
firstName: String!
lastName: String
friends: [Character!]
}
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true
field :friends, [Types::CharacterType], null: true
end
end
GraphQL Fields
{
"data": {
"character": {
"firstName": "Peter",
"lastName": "Griffin",
"friends": [
{
"firstName": "Brian",
"lastName": null
},
{
"firstName": "Homer",
"lastName": "Simpson"
}
]
}
}
}
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL Fields
{
"data": {
"character": {
"firstName": "Peter",
"lastName": "Griffin",
"friends": [
{
"firstName": "Brian",
"lastName": null
},
{
"firstName": "Homer",
"lastName": "Simpson"
}
]
}
}
}
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL Fields
• Arguments

• Resolvers
GraphQL Fields: Arguments
{
"data": {
"character": {
"firstName": "Jon",
"lastName": "wonS",
"friends": [
{
"firstName": "Samwell",
"lastName": "Tarly"
}
]
}
}
}
query {
character {
firstName
lastName(reverse: true)
friends(last: 1) {
firstName
lastName
}
}
}
GraphQL Fields: Arguments
{
"data": {
"character": {
"firstName": "Jon",
"lastName": "wonS",
"friends": [
{
"firstName": "Samwell",
"lastName": "Tarly"
}
]
}
}
}
query {
character {
firstName
lastName(reverse: true)
friends(last: 1) {
firstName
lastName
}
}
}
GraphQL Fields: Arguments
type Character {
firstName: String!
lastName(reverse: Boolean): String
friends(last: Int): [Character!]
}
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true do
argument :reverse, Boolean, required: false
end
field :friends, [Types::CharacterType], null: true do
argument :last, Integer, required: false
end
end
end
GraphQL Fields: Arguments
type Character {
firstName: String!
lastName(reverse: Boolean): String
friends(last: Int): [Character!]
}
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true do
argument :reverse, Boolean, required: false
end
field :friends, [Types::CharacterType], null: true do
argument :last, Integer, required: false
end
end
end
GraphQL Fields: Resolvers
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true
field :full_name, String, null: false
end
end
GraphQL Fields: Resolvers
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true
field :full_name, String, null: false
def full_name
[object.full_name, object.last_name].join(' ')
end
end
end
GraphQL Fields: Resolvers
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true
field :full_name, String, null: false, resolver: Resolvers::FullName
end
end
GraphQL Fields: Resolvers
module Resolvers
class Character < Resolvers::Base
type Character, null: false
argument :id, ID, required: true
def resolve(id:)
Character.find(id)
end
end
end
Scalars
GraphQL Scalars
A GraphQL object type has a name and fields
but at some point those fields have to
become some concrete data. 

That's where the scalar types come in: they
represent the leaves of the query.
GraphQL Scalars: Built-in Types
• Int: A signed 32‐bit integer

• Float: A signed double-precision floating-point value

• String: A UTF‐8 character sequence

• Boolean: true or false

• ID: The ID scalar type represents a unique identifier, often used to
refetch an object or as the key for a cache. The ID type is
serialized in the same way as a String; however, defining it as
an ID signifies that it is not intended to be human‐readable
GraphQL Scalars
In most GraphQL service implementations,
there is also a way to specify custom scalar
types.
GraphQL Scalars: GraphQL-Ruby Scalar Types
• Int: like a JSON or Ruby integer

• Float: like a JSON or Ruby floating point decimal

• String: like a JSON or Ruby string

• Boolean: like a JSON or Ruby boolean (true or false)

• ID: which a specialized String for representing unique object
identifiers

• ISO8601DateTime: an ISO 8601-encoded datetime
GraphQL Scalars: Custom Scalar
class Types::Url < Types::BaseScalar
description "A valid URL, transported as a string"
def self.coerce_input(input_value, context)
url = URI.parse(input_value)
if url.is_a?(URI::HTTP) || url.is_a?(URI::HTTPS)
url
else
raise GraphQL::CoercionError, "#{input_value.inspect} is not a valid URL"
end
end
def self.coerce_result(ruby_value, context)
ruby_value.to_s
end
end
GraphQL Scalars: Custom Scalar
class Types::Url < Types::BaseScalar
description "A valid URL, transported as a string"
def self.coerce_input(input_value, context)
url = URI.parse(input_value)
if url.is_a?(URI::HTTP) || url.is_a?(URI::HTTPS)
url
else
raise GraphQL::CoercionError, "#{input_value.inspect} is not a valid URL"
end
end
def self.coerce_result(ruby_value, context)
ruby_value.to_s
end
end
Enums
GraphQL Enums
Enumerations are similar to custom scalars with the limitation that their
values can only be one of a pre-defined list of strings.
GraphQL Enums
{
"data": {
"character": {
"firstName": "Peter",
"role": "FATHER",
"friends": [
{
"firstName": "Brian",
"role": "PET"
},
{
"firstName": "Stewie",
"role": "SON"
}
]
}
}
}
query {
character {
firstName
role
friends {
firstName
role
}
}
}
GraphQL Enums
enum RoleEnum {
FATHER
MOTHER
SON
DAUGHTER
DOG
}
class Types::RoleEnum < Types::BaseEnum
value ‘FATHER'
value ‘MOTHER'
value ‘SON'
value ‘DAUGHTER'
value ‘PET'
end
GraphQL Enums
enum RoleEnum {
FATHER
MOTHER
SON
DAUGHTER
DOG
}
class Types::RoleEnum < Types::BaseEnum
value 'FATHER', value: 1
value 'MOTHER', value: 2
value 'SON', value: 3
value 'DAUGHTER', value: 4
value 'PET', value: 5
end
GraphQL Enums
enum RoleEnum {
FATHER
MOTHER
SON
DAUGHTER
DOG
}
class Types::RoleEnum < Types::BaseEnum
value 'FATHER', value: :father
value 'MOTHER', value: :mom
value 'SON', value: :son
value 'DAUGHTER', value: :daughter
value 'PET', value: :animal
end
Lists
GraphQL Lists
{
"data": {
"character": {
"firstName": "Peter",
"lastName": "Griffin",
"friends": [
{
"firstName": "Brian",
"lastName": null
},
{
"firstName": "Homer",
"lastName": "Simpson"
}
]
}
}
}
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL Lists
type Character {
firstName: String!
lastName: String
friends: [Character!]
}
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true
field :friends, [Types::CharacterType], null: true
end
end
Non-Null
GraphQL Non-Null
In the GraphQL type system all types are nullable by default. 

This means that a type like Int can take any integer (1, 2, etc.)
or null which represents the absence of any value. 

However, the GraphQL type system allows you to make any type non-
null which means that the type will never produce a null value. 

When using a non-null type there will always be a value.
GraphQL Non-Null
type Character {
firstName: String!
lastName: String
friends: [Character!]!
}
type Character {
firstName: String!
lastName: String
friends: [Character]!
}
type Character {
firstName: String!
lastName: String
friends: [Character!]
}
type Character {
firstName: String!
lastName: String
friends: [Character]
}
GraphQL Non-Null
module Types
class CharacterType < BaseObject
field :first_name, String, null: false
field :last_name, String, null: true
field :friends, [Types::CharacterType, null: true], null: true
field :friends, [Types::CharacterType, null: true], null: false
field :friends, [Types::CharacterType, null: false], null: true
field :friends, [Types::CharacterType, null: false], null: false
end
end
Unions
GraphQL Unions
{
search(in: "Adventure Time") {
__typename
... on Character {
firstName
}
... on land {
name
}
... on Building {
type
}
}
}
{
"data": {
"search": [
{
"__typename": "Character",
"firstName": "Finn"
},
{
"__typename": "Land",
"name": "Land of Ooo"
},
{
"__typename": "Building",
"type": "Fort"
}
]
}
}
GraphQL Unions
union Result = Character | Land | Building
type Character {
firstName: String!
}
type Building {
type: String!
}
type Land {
name: String!
}
type Query {
search: [Result]
}
GraphQL Unions
union Result = Character | Land | Building
type Character {
firstName: String!
}
type Building {
type: String!
}
type Land {
name: String!
}
type Query {
search: [Result]
}
GraphQL Unions
class Types::ResultType < Types::BaseUnion
possible_types Types::CharacterType, Types::LandType, Types::BuildingType
# Optional: if this method is defined, it will override `Schema.resolve_type`
def self.resolve_type(object, context)
if object.is_a?(Character)
Types::CharacterType
elsif object.is_a?(Land)
Types::LandType
else
Types::BuildingType
end
end
end
Interfaces
GraphQL Interfaces
interface Node {
id: ID!
}
interface Person {
firstName: String!
lastName: String
}
type Land implements Node {
id: ID!
name: String!
}
type Character implements Node & Person {
id: ID!
firstName: String!
lastName: String
}
GraphQL Interfaces
module Types::Interfaces::Node
include Types::BaseInterface
field :id, ID, null: false
end
module Types::Interfaces::Person
include Types::BaseInterface
field :first_name, String, null: false
field :last_name, String, null: true
end
module Types
class CharacterType < BaseObject
implements Types::Interfaces::Node
implements Types::Interfaces::Person
end
end
Fragments
GraphQL Fragments
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL Fragments
fragment CharacterFragment on Character {
firstName
lastName
}
query {
character {
...CharacterFragment
friends {
...CharacterFragment
}
}
}
Aliases
GraphQL Aliases
query {
hero: character(hero: true) {
firstName
}
antihero: character(hero: false) {
firstName
}
}
{
"data": {
"hero": {
"firstName": "Harrison",
},
"antihero": {
"firstName": "Sebastian",
}
}
}
Directives
GraphQL Directives
• @deprecated(reason: String) - marks fields as deprecated with messages

• @skip(if: Boolean!) - GraphQL execution skips the field if true by not calling the resolver

• @include(id: Boolean!) - Calls resolver for annotated field if true
GraphQL provides several built-in directives:
GraphQL Directives
query {
character {
firstName
lastName
friends @skip(if: $isAlone){
firstName
lastName
}
}
}
type Character {
firstName: String!
lastName: String
surname: String @deprecated(reason: "Use lastName. Will be removed...")
friends: [Character!]
}
GraphQL Directives: Custom Directive
class Directives::Rest < GraphQL::Schema::Directive
description "..."
locations(
GraphQL::Schema::Directive::FIELD,
GraphQL::Schema::Directive::FRAGMENT_SPREAD,
GraphQL::Schema::Directive::INLINE_FRAGMENT
)
argument :url, String, required: true, description: "..."
def self.include?(obj, args, ctx)
# implementation
end
def self.resolve(obj, args, ctx)
# implementation
end
end
query {
character @rest(url: "/path") {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL Directives: Custom Directive
Input Objects
GraphQL Input Objects
mutation CreateCharacter(
$firstName: String!
$lastName: String
$role: RoleEnum!
) {
createCharacter(
firstName: $firstName
lastName: $lastName
role: $role
) {
firstName
lastName
role
}
}
mutation CreateCharacter(
$input: CharacterAttributes!
) {
createCharacter(input: $input) {
firstName
lastName
role
}
}
GraphQL Input Objects
input CharacterAttributes {
firstName: String!
lastName: String
role: RoleEnum!
}
class Types::CharacterAttributes < Types::BaseInputObject
argument :first_name, String, required: true
argument :last_name, String, required: false
argument :role, Types::RoleEnum, required: false
end
Schema
🍒
GraphQL Schema
schema {
query: Query
}
GraphQL Schema
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
class MySchema < GraphQL::Schema
# Required:
query Types::QueryType
# Optional:
mutation Types::MutationType
subscription Types::SubscriptionType
end
GraphQL Schema
class Types::QueryType < GraphQL::Schema::Object
field :character, Types::CharacterType, resolver: Resolvers::Character
end
# Similarly:
class Types::MutationType < GraphQL::Schema::Object
# ...
end
# and
class Types::SubscriptionType < GraphQL::Schema::Object
# ...
end
type Query {
character(id: ID!): CharacterType
}
What GraphQL SDL gives us?
What GraphQL SDL gives us?
Documentation
What GraphQL SDL gives us?
Documentation is the first class citizen in GraphQL
GraphQL Execution
How to do with GraphQL?
🚀
When executing a GraphQL query one of the very first things the server needs to do
is transform the query (currently a string) into something it understands.
Transport
Transport
• HTTP POST

• one endpoint (e.g. /graphql)

• response code 200 OK
Transport
GraphQL-Ruby Phases of Execution
• Tokenize: splits the string into a stream of tokens

• Parse: builds an abstract syntax tree (AST) out of the stream of tokens

• Validate: validates the incoming AST as a valid query for the schema

• Rewrite: builds a tree of nodes which express the query in a simpler way than the
AST

• Analyze: if there are any query analyzers, they are run

• Execute: the query is traversed, resolve functions are called and the response is built

• Respond: the response is returned as a Hash
Tokenize & Parsing
GraphQL has its own grammar.

We need this rules to split up the query.

 GraphQL Ruby uses a tool called Ragel to generate its lexer.
How to understand that we have valid data?
How to verify incoming data?
• Breaks up a stream of characters (in our case a GraphQL query) into
tokens

• Turns sequences of tokens into a more abstract representation of the
language
Lexer
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL.scan(query) =>
[
(QUERY "query" [2:1]),
(LCURLY "{" [2:7]),
(IDENTIFIER "character" [3:3]),
(LCURLY "{" [3:13]),
(IDENTIFIER "firstName" [4:5]),
(IDENTIFIER "lastName" [5:5]),
(IDENTIFIER "friends" [6:5]),
(LCURLY "{" [6:13]),
(IDENTIFIER "firstName" [7:7]),
(IDENTIFIER "lastName" [8:7]),
(RCURLY "}" [9:5]),
(RCURLY "}" [10:3]),
(RCURLY "}" [11:1])
]
Parser
query {
character {
firstName
lastName
friends {
firstName
lastName
}
}
}
GraphQL.parse(query) =>
#<GraphQL::Language::Nodes::Document:0x00007fbd8ae3dec0
@definitions=
[#<GraphQL::Language::Nodes::OperationDefinition:…
@col=1,
@directives=[],
@filename=nil,
@line=2,
@name=nil,
@operation_type="query",
@selections=
[#<GraphQL::Language::Nodes::Field:…
@alias=nil,
@arguments=[],
@col=3,
@directives=[],
@filename=nil,
@line=3,
@name="character"
Lexer & Parser
Javascript implementation of GraphQL has hand-written lexer and parser.

GraphQL Ruby uses a tool called Ragel to generate its lexer.

GraphQL Ruby uses a tool called Racc to generate its parser.
GraphQL-Ruby Phases of Execution
Tokenizing and Parsing are fundamental steps in the execution process.

Validating, Rewriting, Analyzing, Executing are just details of the implementation.
Pitfalls
🤕
Pitfalls
• Authentication

• File uploading

• N+1

• Caching

• Performance
Authentication
• One endpoint

• Handle guests and registered users

• Fetch schema definition

• Solutions:

1. auth processes with GraphQL

2. auth by tokens (JWT, OAuth) (check tokens)
File uploading
• Vanilla GraphQL doesn’t support throwing raw files into your mutations

• Solutions:

1. Base64 Encoding

2. Separate Upload Requests

3. GraphQL Multipart Requests(most recommended)
N+1
• The server executes multiple unnecessary round trips to data stores for
nested data

• Problem in how GraphQL works, not Ruby

• Solutions:

1. preload data

2. gem ‘graphql-batch’

3. gem ‘batch-loader’
Caching
• Transport-agnostic

• Uses POST with HTTP

• Don’t have url with identifier

• Solution:

1. Server side caching(Memcache, Redis, etc.)
Performance
• Big queries can bring your server down to its knees

• Solutions:

1. Set query timeout

2. Check query depth

3. Check query complexity
Links
• https://graphql.org

• https://gql.foundation

• https://graphql.github.io/graphql-spec

• https://graphql-ruby.org

• https://github.com/valikos/rm-27
Thanks
🙌
Questions?
🤔

More Related Content

What's hot

Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Ramamohan Chokkam
 
Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)
Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)
Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)Andrés Viedma Peláez
 
Modelling Data as Graphs (Neo4j)
Modelling Data as Graphs (Neo4j)Modelling Data as Graphs (Neo4j)
Modelling Data as Graphs (Neo4j)Michal Bachman
 
Scala In The Wild
Scala In The WildScala In The Wild
Scala In The Wilddjspiewak
 
Cutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optionalCutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optionalGraham Charters
 
Introduction to JSON & Ajax
Introduction to JSON & AjaxIntroduction to JSON & Ajax
Introduction to JSON & AjaxSeble Nigussie
 
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...Codemotion
 
Why Java Needs Hierarchical Data
Why Java Needs Hierarchical DataWhy Java Needs Hierarchical Data
Why Java Needs Hierarchical DataMarakana Inc.
 
Building Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraBuilding Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraMarkus Lanthaler
 
Использование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайтуИспользование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайтуOlga Lavrentieva
 
Graph and RDF databases
Graph and RDF databasesGraph and RDF databases
Graph and RDF databasesNassim Bahri
 
Amsterdam museum as five star linked data
Amsterdam museum as five star linked dataAmsterdam museum as five star linked data
Amsterdam museum as five star linked dataVictor de Boer
 
The Gremlin in the Graph
The Gremlin in the GraphThe Gremlin in the Graph
The Gremlin in the GraphMarko Rodriguez
 
Json - ideal for data interchange
Json - ideal for data interchangeJson - ideal for data interchange
Json - ideal for data interchangeChristoph Santschi
 
JSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataJSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataGregg Kellogg
 
Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs - Front in Bahia...
Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs  - Front in Bahia...Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs  - Front in Bahia...
Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs - Front in Bahia...Ícaro Medeiros
 
It's 2017, and I still want to sell you a graph database
It's 2017, and I still want to sell you a graph databaseIt's 2017, and I still want to sell you a graph database
It's 2017, and I still want to sell you a graph databaseSwanand Pagnis
 
Computational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data WranglingComputational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data Wranglingjakehofman
 

What's hot (20)

Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268Automatically generating-json-from-java-objects-java-objects268
Automatically generating-json-from-java-objects-java-objects268
 
Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)
Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)
Poniendo Kotlin en producción a palos (Kotlin in production, the hard way)
 
Modelling Data as Graphs (Neo4j)
Modelling Data as Graphs (Neo4j)Modelling Data as Graphs (Neo4j)
Modelling Data as Graphs (Neo4j)
 
Scala In The Wild
Scala In The WildScala In The Wild
Scala In The Wild
 
Cutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optionalCutting through the fog of microservices: lightsabers optional
Cutting through the fog of microservices: lightsabers optional
 
ETL into Neo4j
ETL into Neo4jETL into Neo4j
ETL into Neo4j
 
Introduction to JSON & Ajax
Introduction to JSON & AjaxIntroduction to JSON & Ajax
Introduction to JSON & Ajax
 
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
 
Why Java Needs Hierarchical Data
Why Java Needs Hierarchical DataWhy Java Needs Hierarchical Data
Why Java Needs Hierarchical Data
 
Building Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraBuilding Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and Hydra
 
Использование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайтуИспользование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайту
 
Graph and RDF databases
Graph and RDF databasesGraph and RDF databases
Graph and RDF databases
 
Amsterdam museum as five star linked data
Amsterdam museum as five star linked dataAmsterdam museum as five star linked data
Amsterdam museum as five star linked data
 
The Gremlin in the Graph
The Gremlin in the GraphThe Gremlin in the Graph
The Gremlin in the Graph
 
Json - ideal for data interchange
Json - ideal for data interchangeJson - ideal for data interchange
Json - ideal for data interchange
 
JSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataJSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked Data
 
JSON-LD and MongoDB
JSON-LD and MongoDBJSON-LD and MongoDB
JSON-LD and MongoDB
 
Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs - Front in Bahia...
Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs  - Front in Bahia...Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs  - Front in Bahia...
Linked Data in Use: Schema.org, JSON-LD and hypermedia APIs - Front in Bahia...
 
It's 2017, and I still want to sell you a graph database
It's 2017, and I still want to sell you a graph databaseIt's 2017, and I still want to sell you a graph database
It's 2017, and I still want to sell you a graph database
 
Computational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data WranglingComputational Social Science, Lecture 09: Data Wrangling
Computational Social Science, Lecture 09: Data Wrangling
 

Similar to What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27

Overview of GraphQL & Clients
Overview of GraphQL & ClientsOverview of GraphQL & Clients
Overview of GraphQL & ClientsPokai Chang
 
Better APIs with GraphQL
Better APIs with GraphQL Better APIs with GraphQL
Better APIs with GraphQL Josh Price
 
The Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend ArchitectureThe Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend ArchitectureNikolas Burk
 
GraphQL Subscriptions
GraphQL SubscriptionsGraphQL Subscriptions
GraphQL SubscriptionsNikolas Burk
 
Next-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and PrismaNext-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and PrismaNikolas Burk
 
GraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedGraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedMarcinStachniuk
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
Copy/paste detector for source code on javascript
Copy/paste detector for source code on javascript Copy/paste detector for source code on javascript
Copy/paste detector for source code on javascript Andrey Kucherenko
 
Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017
Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017
Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017Codemotion
 
GraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoGraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoMarcinStachniuk
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...NoSQLmatters
 
06. ElasticSearch : Mapping and Analysis
06. ElasticSearch : Mapping and Analysis06. ElasticSearch : Mapping and Analysis
06. ElasticSearch : Mapping and AnalysisOpenThink Labs
 
Harnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, Germany
Harnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, GermanyHarnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, Germany
Harnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, GermanyAndré Ricardo Barreto de Oliveira
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Scott Wlaschin
 
d3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlind3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in BerlinToshiaki Katayama
 
[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za mało[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za małoMarcinStachniuk
 

Similar to What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27 (20)

Overview of GraphQL & Clients
Overview of GraphQL & ClientsOverview of GraphQL & Clients
Overview of GraphQL & Clients
 
Better APIs with GraphQL
Better APIs with GraphQL Better APIs with GraphQL
Better APIs with GraphQL
 
The Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend ArchitectureThe Serverless GraphQL Backend Architecture
The Serverless GraphQL Backend Architecture
 
GraphQL Subscriptions
GraphQL SubscriptionsGraphQL Subscriptions
GraphQL Subscriptions
 
HyperGraphQL
HyperGraphQLHyperGraphQL
HyperGraphQL
 
Advanced Json
Advanced JsonAdvanced Json
Advanced Json
 
Next-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and PrismaNext-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and Prisma
 
GraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedGraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learned
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
Copy/paste detector for source code on javascript
Copy/paste detector for source code on javascript Copy/paste detector for source code on javascript
Copy/paste detector for source code on javascript
 
Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017
Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017
Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017
 
GraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoGraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za mało
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...
 
06. ElasticSearch : Mapping and Analysis
06. ElasticSearch : Mapping and Analysis06. ElasticSearch : Mapping and Analysis
06. ElasticSearch : Mapping and Analysis
 
Harnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, Germany
Harnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, GermanyHarnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, Germany
Harnessing The Power of Search - Liferay DEVCON 2015, Darmstadt, Germany
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 
d3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlind3sparql.js demo at SWAT4LS 2014 in Berlin
d3sparql.js demo at SWAT4LS 2014 in Berlin
 
[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za mało[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za mało
 

More from Ruby Meditation

Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30
Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30
Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30Ruby Meditation
 
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...Ruby Meditation
 
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29Ruby Meditation
 
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...Ruby Meditation
 
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 Ruby Meditation
 
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28Ruby Meditation
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Ruby Meditation
 
Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...
Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...
Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...Ruby Meditation
 
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Ruby Meditation
 
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...Ruby Meditation
 
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26Ruby Meditation
 
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Ruby Meditation
 
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Ruby Meditation
 
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26Ruby Meditation
 
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25Ruby Meditation
 
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...Ruby Meditation
 
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...Ruby Meditation
 
Rails App performance at the limit - Bogdan Gusiev
Rails App performance at the limit - Bogdan GusievRails App performance at the limit - Bogdan Gusiev
Rails App performance at the limit - Bogdan GusievRuby Meditation
 
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23Ruby Meditation
 
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...Ruby Meditation
 

More from Ruby Meditation (20)

Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30
Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30
Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30
 
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...
 
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29
 
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
 
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28
 
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
 
Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...
Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...
Performance Optimization 101 for Ruby developers - Nihad Abbasov (ENG) | Ruby...
 
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
 
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
 
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26
 
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
 
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
 
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
 
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
 
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
 
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
 
Rails App performance at the limit - Bogdan Gusiev
Rails App performance at the limit - Bogdan GusievRails App performance at the limit - Bogdan Gusiev
Rails App performance at the limit - Bogdan Gusiev
 
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
 
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
 

Recently uploaded

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 

Recently uploaded (20)

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 

What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27

  • 1. What/how to do with GraphQL? Valentyn Ostakh #27
  • 2. query { me { firstName lastName company position socialLinks { name url } } } { "data": { "me": { "firstName": "Valentyn", "lastName": "Ostakh", "company": "RubyGarage", "position": "Ruby/JS developer", "socialLinks": [ { "name": "facebook", "url": "https://facebook.com/valikos" }, { "name": "twitter", "url": "https://twitter.com/valikos_ost" }, { "name": "github", "url": "https://github.com/valikos" } ] } } }
  • 3. Agenda • Introduction into GraphQL • GraphQL SDL(Schema Definition Language) • GraphQL Execution • Pitfalls
  • 5. What is GraphQL? • A query language for API • A type system of defined data • A platform of both backend + frontend applications
  • 6. More About GraphQL • GraphQL was developed internally by Facebook in 2012 before being publicly released in 2015 • The idea of GraphQL became from the frontend team • GraphQL services can be written in any language • GraphQL is transport-agnostic • GraphQL represents data in graphs
  • 7. GraphQL SDL What to do with GraphQL? 🗺
  • 8. GraphQL SDL GraphQL schema is at the center of any GraphQL server implementation. GraphQL schema describes the functionality available to the clients who connect to it
  • 9. GraphQL SDL • Schema • Object Types • Fields • Scalars • Enums • Lists • Non-Null • Directives • Aliases • Interfaces • Unions • Fragments • Input Objects
  • 11. GraphQL Object Type { "data": { "character": { "firstName": "Peter", "lastName": "Griffin", "friends": [ { "firstName": "Brian", "lastName": null }, { "firstName": "Homer", "lastName": "Simpson" } ] } } } query { character { firstName lastName friends { firstName lastName } } }
  • 12. GraphQL Object Type { "data": { "character": { "firstName": "Peter", "lastName": "Griffin", "friends": [ { "firstName": "Brian", "lastName": null }, { "firstName": "Homer", "lastName": "Simpson" } ] } } } query { character { firstName lastName friends { firstName lastName } } }
  • 13. GraphQL Object Type type Character { firstName: String! lastName: String friends: [Character!] } module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true field :friends, [Types::CharacterType], null: true end end
  • 15. GraphQL Fields type Character { firstName: String! lastName: String friends: [Character!] } module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true field :friends, [Types::CharacterType], null: true end end
  • 16. GraphQL Fields { "data": { "character": { "firstName": "Peter", "lastName": "Griffin", "friends": [ { "firstName": "Brian", "lastName": null }, { "firstName": "Homer", "lastName": "Simpson" } ] } } } query { character { firstName lastName friends { firstName lastName } } }
  • 17. GraphQL Fields { "data": { "character": { "firstName": "Peter", "lastName": "Griffin", "friends": [ { "firstName": "Brian", "lastName": null }, { "firstName": "Homer", "lastName": "Simpson" } ] } } } query { character { firstName lastName friends { firstName lastName } } }
  • 19. GraphQL Fields: Arguments { "data": { "character": { "firstName": "Jon", "lastName": "wonS", "friends": [ { "firstName": "Samwell", "lastName": "Tarly" } ] } } } query { character { firstName lastName(reverse: true) friends(last: 1) { firstName lastName } } }
  • 20. GraphQL Fields: Arguments { "data": { "character": { "firstName": "Jon", "lastName": "wonS", "friends": [ { "firstName": "Samwell", "lastName": "Tarly" } ] } } } query { character { firstName lastName(reverse: true) friends(last: 1) { firstName lastName } } }
  • 21. GraphQL Fields: Arguments type Character { firstName: String! lastName(reverse: Boolean): String friends(last: Int): [Character!] } module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true do argument :reverse, Boolean, required: false end field :friends, [Types::CharacterType], null: true do argument :last, Integer, required: false end end end
  • 22. GraphQL Fields: Arguments type Character { firstName: String! lastName(reverse: Boolean): String friends(last: Int): [Character!] } module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true do argument :reverse, Boolean, required: false end field :friends, [Types::CharacterType], null: true do argument :last, Integer, required: false end end end
  • 23. GraphQL Fields: Resolvers module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true field :full_name, String, null: false end end
  • 24. GraphQL Fields: Resolvers module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true field :full_name, String, null: false def full_name [object.full_name, object.last_name].join(' ') end end end
  • 25. GraphQL Fields: Resolvers module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true field :full_name, String, null: false, resolver: Resolvers::FullName end end
  • 26. GraphQL Fields: Resolvers module Resolvers class Character < Resolvers::Base type Character, null: false argument :id, ID, required: true def resolve(id:) Character.find(id) end end end
  • 28. GraphQL Scalars A GraphQL object type has a name and fields but at some point those fields have to become some concrete data. That's where the scalar types come in: they represent the leaves of the query.
  • 29. GraphQL Scalars: Built-in Types • Int: A signed 32‐bit integer • Float: A signed double-precision floating-point value • String: A UTF‐8 character sequence • Boolean: true or false • ID: The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache. The ID type is serialized in the same way as a String; however, defining it as an ID signifies that it is not intended to be human‐readable
  • 30. GraphQL Scalars In most GraphQL service implementations, there is also a way to specify custom scalar types.
  • 31. GraphQL Scalars: GraphQL-Ruby Scalar Types • Int: like a JSON or Ruby integer • Float: like a JSON or Ruby floating point decimal • String: like a JSON or Ruby string • Boolean: like a JSON or Ruby boolean (true or false) • ID: which a specialized String for representing unique object identifiers • ISO8601DateTime: an ISO 8601-encoded datetime
  • 32. GraphQL Scalars: Custom Scalar class Types::Url < Types::BaseScalar description "A valid URL, transported as a string" def self.coerce_input(input_value, context) url = URI.parse(input_value) if url.is_a?(URI::HTTP) || url.is_a?(URI::HTTPS) url else raise GraphQL::CoercionError, "#{input_value.inspect} is not a valid URL" end end def self.coerce_result(ruby_value, context) ruby_value.to_s end end
  • 33. GraphQL Scalars: Custom Scalar class Types::Url < Types::BaseScalar description "A valid URL, transported as a string" def self.coerce_input(input_value, context) url = URI.parse(input_value) if url.is_a?(URI::HTTP) || url.is_a?(URI::HTTPS) url else raise GraphQL::CoercionError, "#{input_value.inspect} is not a valid URL" end end def self.coerce_result(ruby_value, context) ruby_value.to_s end end
  • 34. Enums
  • 35. GraphQL Enums Enumerations are similar to custom scalars with the limitation that their values can only be one of a pre-defined list of strings.
  • 36. GraphQL Enums { "data": { "character": { "firstName": "Peter", "role": "FATHER", "friends": [ { "firstName": "Brian", "role": "PET" }, { "firstName": "Stewie", "role": "SON" } ] } } } query { character { firstName role friends { firstName role } } }
  • 37. GraphQL Enums enum RoleEnum { FATHER MOTHER SON DAUGHTER DOG } class Types::RoleEnum < Types::BaseEnum value ‘FATHER' value ‘MOTHER' value ‘SON' value ‘DAUGHTER' value ‘PET' end
  • 38. GraphQL Enums enum RoleEnum { FATHER MOTHER SON DAUGHTER DOG } class Types::RoleEnum < Types::BaseEnum value 'FATHER', value: 1 value 'MOTHER', value: 2 value 'SON', value: 3 value 'DAUGHTER', value: 4 value 'PET', value: 5 end
  • 39. GraphQL Enums enum RoleEnum { FATHER MOTHER SON DAUGHTER DOG } class Types::RoleEnum < Types::BaseEnum value 'FATHER', value: :father value 'MOTHER', value: :mom value 'SON', value: :son value 'DAUGHTER', value: :daughter value 'PET', value: :animal end
  • 40. Lists
  • 41. GraphQL Lists { "data": { "character": { "firstName": "Peter", "lastName": "Griffin", "friends": [ { "firstName": "Brian", "lastName": null }, { "firstName": "Homer", "lastName": "Simpson" } ] } } } query { character { firstName lastName friends { firstName lastName } } }
  • 42. GraphQL Lists type Character { firstName: String! lastName: String friends: [Character!] } module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true field :friends, [Types::CharacterType], null: true end end
  • 44. GraphQL Non-Null In the GraphQL type system all types are nullable by default. This means that a type like Int can take any integer (1, 2, etc.) or null which represents the absence of any value. However, the GraphQL type system allows you to make any type non- null which means that the type will never produce a null value. When using a non-null type there will always be a value.
  • 45. GraphQL Non-Null type Character { firstName: String! lastName: String friends: [Character!]! } type Character { firstName: String! lastName: String friends: [Character]! } type Character { firstName: String! lastName: String friends: [Character!] } type Character { firstName: String! lastName: String friends: [Character] }
  • 46. GraphQL Non-Null module Types class CharacterType < BaseObject field :first_name, String, null: false field :last_name, String, null: true field :friends, [Types::CharacterType, null: true], null: true field :friends, [Types::CharacterType, null: true], null: false field :friends, [Types::CharacterType, null: false], null: true field :friends, [Types::CharacterType, null: false], null: false end end
  • 48. GraphQL Unions { search(in: "Adventure Time") { __typename ... on Character { firstName } ... on land { name } ... on Building { type } } } { "data": { "search": [ { "__typename": "Character", "firstName": "Finn" }, { "__typename": "Land", "name": "Land of Ooo" }, { "__typename": "Building", "type": "Fort" } ] } }
  • 49. GraphQL Unions union Result = Character | Land | Building type Character { firstName: String! } type Building { type: String! } type Land { name: String! } type Query { search: [Result] }
  • 50. GraphQL Unions union Result = Character | Land | Building type Character { firstName: String! } type Building { type: String! } type Land { name: String! } type Query { search: [Result] }
  • 51. GraphQL Unions class Types::ResultType < Types::BaseUnion possible_types Types::CharacterType, Types::LandType, Types::BuildingType # Optional: if this method is defined, it will override `Schema.resolve_type` def self.resolve_type(object, context) if object.is_a?(Character) Types::CharacterType elsif object.is_a?(Land) Types::LandType else Types::BuildingType end end end
  • 53. GraphQL Interfaces interface Node { id: ID! } interface Person { firstName: String! lastName: String } type Land implements Node { id: ID! name: String! } type Character implements Node & Person { id: ID! firstName: String! lastName: String }
  • 54. GraphQL Interfaces module Types::Interfaces::Node include Types::BaseInterface field :id, ID, null: false end module Types::Interfaces::Person include Types::BaseInterface field :first_name, String, null: false field :last_name, String, null: true end module Types class CharacterType < BaseObject implements Types::Interfaces::Node implements Types::Interfaces::Person end end
  • 56. GraphQL Fragments query { character { firstName lastName friends { firstName lastName } } }
  • 57. GraphQL Fragments fragment CharacterFragment on Character { firstName lastName } query { character { ...CharacterFragment friends { ...CharacterFragment } } }
  • 59. GraphQL Aliases query { hero: character(hero: true) { firstName } antihero: character(hero: false) { firstName } } { "data": { "hero": { "firstName": "Harrison", }, "antihero": { "firstName": "Sebastian", } } }
  • 61. GraphQL Directives • @deprecated(reason: String) - marks fields as deprecated with messages • @skip(if: Boolean!) - GraphQL execution skips the field if true by not calling the resolver • @include(id: Boolean!) - Calls resolver for annotated field if true GraphQL provides several built-in directives:
  • 62. GraphQL Directives query { character { firstName lastName friends @skip(if: $isAlone){ firstName lastName } } } type Character { firstName: String! lastName: String surname: String @deprecated(reason: "Use lastName. Will be removed...") friends: [Character!] }
  • 63. GraphQL Directives: Custom Directive class Directives::Rest < GraphQL::Schema::Directive description "..." locations( GraphQL::Schema::Directive::FIELD, GraphQL::Schema::Directive::FRAGMENT_SPREAD, GraphQL::Schema::Directive::INLINE_FRAGMENT ) argument :url, String, required: true, description: "..." def self.include?(obj, args, ctx) # implementation end def self.resolve(obj, args, ctx) # implementation end end
  • 64. query { character @rest(url: "/path") { firstName lastName friends { firstName lastName } } } GraphQL Directives: Custom Directive
  • 66. GraphQL Input Objects mutation CreateCharacter( $firstName: String! $lastName: String $role: RoleEnum! ) { createCharacter( firstName: $firstName lastName: $lastName role: $role ) { firstName lastName role } } mutation CreateCharacter( $input: CharacterAttributes! ) { createCharacter(input: $input) { firstName lastName role } }
  • 67. GraphQL Input Objects input CharacterAttributes { firstName: String! lastName: String role: RoleEnum! } class Types::CharacterAttributes < Types::BaseInputObject argument :first_name, String, required: true argument :last_name, String, required: false argument :role, Types::RoleEnum, required: false end
  • 70. GraphQL Schema schema { query: Query mutation: Mutation subscription: Subscription } class MySchema < GraphQL::Schema # Required: query Types::QueryType # Optional: mutation Types::MutationType subscription Types::SubscriptionType end
  • 71. GraphQL Schema class Types::QueryType < GraphQL::Schema::Object field :character, Types::CharacterType, resolver: Resolvers::Character end # Similarly: class Types::MutationType < GraphQL::Schema::Object # ... end # and class Types::SubscriptionType < GraphQL::Schema::Object # ... end type Query { character(id: ID!): CharacterType }
  • 72. What GraphQL SDL gives us?
  • 73. What GraphQL SDL gives us? Documentation
  • 74. What GraphQL SDL gives us? Documentation is the first class citizen in GraphQL
  • 75. GraphQL Execution How to do with GraphQL? 🚀
  • 76. When executing a GraphQL query one of the very first things the server needs to do is transform the query (currently a string) into something it understands. Transport
  • 77. Transport • HTTP POST • one endpoint (e.g. /graphql) • response code 200 OK
  • 79. GraphQL-Ruby Phases of Execution • Tokenize: splits the string into a stream of tokens • Parse: builds an abstract syntax tree (AST) out of the stream of tokens • Validate: validates the incoming AST as a valid query for the schema • Rewrite: builds a tree of nodes which express the query in a simpler way than the AST • Analyze: if there are any query analyzers, they are run • Execute: the query is traversed, resolve functions are called and the response is built • Respond: the response is returned as a Hash
  • 80.
  • 81. Tokenize & Parsing GraphQL has its own grammar. We need this rules to split up the query.  GraphQL Ruby uses a tool called Ragel to generate its lexer. How to understand that we have valid data?
  • 82. How to verify incoming data? • Breaks up a stream of characters (in our case a GraphQL query) into tokens • Turns sequences of tokens into a more abstract representation of the language
  • 83. Lexer query { character { firstName lastName friends { firstName lastName } } } GraphQL.scan(query) => [ (QUERY "query" [2:1]), (LCURLY "{" [2:7]), (IDENTIFIER "character" [3:3]), (LCURLY "{" [3:13]), (IDENTIFIER "firstName" [4:5]), (IDENTIFIER "lastName" [5:5]), (IDENTIFIER "friends" [6:5]), (LCURLY "{" [6:13]), (IDENTIFIER "firstName" [7:7]), (IDENTIFIER "lastName" [8:7]), (RCURLY "}" [9:5]), (RCURLY "}" [10:3]), (RCURLY "}" [11:1]) ]
  • 84. Parser query { character { firstName lastName friends { firstName lastName } } } GraphQL.parse(query) => #<GraphQL::Language::Nodes::Document:0x00007fbd8ae3dec0 @definitions= [#<GraphQL::Language::Nodes::OperationDefinition:… @col=1, @directives=[], @filename=nil, @line=2, @name=nil, @operation_type="query", @selections= [#<GraphQL::Language::Nodes::Field:… @alias=nil, @arguments=[], @col=3, @directives=[], @filename=nil, @line=3, @name="character"
  • 85. Lexer & Parser Javascript implementation of GraphQL has hand-written lexer and parser. GraphQL Ruby uses a tool called Ragel to generate its lexer. GraphQL Ruby uses a tool called Racc to generate its parser.
  • 86. GraphQL-Ruby Phases of Execution Tokenizing and Parsing are fundamental steps in the execution process. Validating, Rewriting, Analyzing, Executing are just details of the implementation.
  • 88. Pitfalls • Authentication • File uploading • N+1 • Caching • Performance
  • 89. Authentication • One endpoint • Handle guests and registered users • Fetch schema definition • Solutions: 1. auth processes with GraphQL 2. auth by tokens (JWT, OAuth) (check tokens)
  • 90. File uploading • Vanilla GraphQL doesn’t support throwing raw files into your mutations • Solutions: 1. Base64 Encoding 2. Separate Upload Requests 3. GraphQL Multipart Requests(most recommended)
  • 91. N+1 • The server executes multiple unnecessary round trips to data stores for nested data • Problem in how GraphQL works, not Ruby • Solutions: 1. preload data 2. gem ‘graphql-batch’ 3. gem ‘batch-loader’
  • 92. Caching • Transport-agnostic • Uses POST with HTTP • Don’t have url with identifier • Solution: 1. Server side caching(Memcache, Redis, etc.)
  • 93. Performance • Big queries can bring your server down to its knees • Solutions: 1. Set query timeout 2. Check query depth 3. Check query complexity
  • 94. Links • https://graphql.org • https://gql.foundation • https://graphql.github.io/graphql-spec • https://graphql-ruby.org • https://github.com/valikos/rm-27