GraphQL pilot
at ING Investments
Mikhail Kuznetcov
The Future of Web Technology @ Webdev Zwolle
October 2019
About me
GraphQL pilot at ING Investments
Mikhail Kuznetcov
Developer at ING Investments
Twitter: @legkoletat
Github: github.com/shershen08
@legkoletat
Agenda
1. GraphQL introduction
2. Pilot project at ING Investments
GraphQL pilot at ING Investments @legkoletat
What is GraphQL and how to use it
1. Introduction
Overview
● A data query language specification
● Introduced by Facebook, open source 2015
● Implemented in JavaScript, Perl, Python, Ruby,
Java, C#, Scala, Go, PHP, etc
GraphQL pilot at ING Investments
Companies using
GraphQL include:
@legkoletat
GraphQL pilot at ING Investments @legkoletat
Benefits of GraphQL
● Typed contract layer
● Several resources in single call
● Granular control over the data composition
● Arguments can be passed on any level of the request
● Versioning and documentation
● Solid ecosystem (GraphiQL, GraphQL Playground, eslint plugin, etc)
GraphQL pilot at ING Investments @legkoletat
Request example
Results in
GraphQL pilot at ING Investments @legkoletat
Terminology
GraphQL pilot at ING Investments
Types
Queries
Mutations
Client:
1. Map variables to query
2. Do a POST call to API
3. Handle response(s)
Server:
● Resolver functions
● Shared context data
@legkoletat
Subscriptions
GraphQL types
● Int, Float, String, Boolean, ID
● Union types
● Lists
● Scalar types
● Non-Null markers
● __abc - system fields
GraphQL pilot at ING Investments
scalar Date
enum MessageStatus {
SENT
VIEWED
DELETED
}
type Picture {
width: Int!
height: Int!
url: String
status: MessageStatus
}
union Message = Text | Picture | Sound;
type Chat {
name: String!
picture: Picture
dateCreated: Date
messages: [Message]!
}
/simple-messenger-schema.graphql
@legkoletat
GraphQL queries
● Like GET in REST
● Name + Structure + Arguments
● Fragments
● @deffer for slow requests
● @deprecated and other
annotations
query {
getUsers(first:2) {
name
groups {
id,
title
...latest Post
}
}
}
GraphQL pilot at ING Investments @legkoletat
GraphQL mutations
● Like POST/DELETE/PUT
in REST
● Can return back the data
mutation newUserMutation {
UserCreate(firstName: "John", lastName: "Snow") {
id
isKing
}
}
mutation DeleteUser {
deleteUser(id: 1234) {
dateCreated
}
}
GraphQL pilot at ING Investments @legkoletat
GraphQL tools
GraphQL pilot at ING Investments @legkoletat
Demo time
https://developer.github.com/v4/explorer/
+
Queries:gist.github.com/shershen08/70c7d4b502bf94cef
0c1a5f726b03011
GraphQL call E2E
contentful.com/blog/2018/07/04/graphql-abstract-syntax-tree-new-schema/GraphQL pilot at ING Investments @legkoletat
Frontend
● Vanilla JS: a POST with
JSON
● Apollo, Relay,
framework-specific clients
fetch('/graphql', {
method: 'POST',
body: JSON.stringify({
query: '{ products { code } }',
variables: {} }),
})
.then(res => res.json())
.then(res => console.log(res.data));
GraphQL pilot at ING Investments
/index.html
@legkoletat
GraphQL at scale
Schema stitching
Apollo federation
GraphQL pilot at ING Investments @legkoletat
2. GraphQL in ING
Investments
Details about pilot scope and implementation
Motivation
● Code duplication
● Model inconsistencies
● Overfetching data
GraphQL pilot at ING Investments @legkoletat
Change:
● 1 call instead of 2
● 1 endpoint instead of 2
Query:
query {
instrumentDetails
instrumentPriceHistory
}
Pilot page
GraphQL pilot at ING Investments @legkoletat
Frontend
Frontend schema
GraphQL pilot at ING Investments
enum Period {
ALL_TIME
FIVE_YEARS
ONE_DAY
...
}
enum RecommendationEnum {
BUY
HOLD
...
}
scalar OffsetDateTime
type InstrumentDetails {
closePriceValue: PriceValue
currency: String
currentPriceValue: PriceValue
...
/src/schema.grapql
@legkoletat
Scalar types
GraphQL pilot at ING Investments
const AppNumberType = new GraphQLScalarType({
name: 'Number',
parseValue(value) {
//...
return value;
},
serialize(value) {
//...
return value;
},
});
const typeResolvers = {
BigDecimal: AppNumberType,
Long: AppNumberType,
// ..
};
@legkoletat
Frontend: mocking
GraphQL pilot at ING Investments
Node + expressJS
$: npm start:with-mocks
/api/path/ok.json
/api/another-path/ok.json
/gql.js
const {makeExecutableSchema,
addMockFunctionsToSchema} =
require('graphql-tools');
const schema = makeExecutableSchema({
typeDefs,
typeResolvers,
});
addMockFunctionsToSchema({
schema,
mocks,
preserveResolvers: false,
});
Frontend app
/demo/mocks/..
@legkoletat
Backend
Architecture
● Java Spring microservices
● Experience service
● graphql-java lib
GraphQL pilot at ING Investments
Experience service
Frontends
Service A
Service B
Service C
GraphQL
REST
REST
@legkoletat
Graphql-spqr
● Schema first vs Code-first
● graphql-spqr provides code first approach
● Code-first => no *.grapql file in backend
GraphQL pilot at ING Investments
class UserService {
@GraphQLQuery(name = "user")
public User getById(@GraphQLArgument(name = "id") Integer id) {
@legkoletat
Errors
@Data
public class AppGraphQLError implements GraphQLError {
private String message;
private int errorCode;
private ErrorType errorType;
private List<SourceLocation> locations;
// ...
}
GraphQL pilot at ING Investments
Map to custom error
Feign service
GraphQL: status 200 with
“errors” property
401/403/500 HTTP Code
@legkoletat
Complexity calculation
graphql:
maxComplexity: 100
queryComplexities:
instrumentDetails: 20
instrumentPriceHistory: 60
GraphQL pilot at ING Investments
Complexity check validator
GraphQL endpoint
Service layer
Config
FieldComplexityCalculator
@legkoletat
Results
Pilot preliminary results
GraphQL pilot at ING Investments
● User experience
● System complexity
● Developer experience
@legkoletat
Further challenges
GraphQL pilot at ING Investments
● Adding mobile client
● Better tracing and logging
● Caching
● Possible Schema duplication
● Reuse of the REST services
@legkoletat
Thank you!
Any questions?
Share your feedback
bit.ly/zwollemeetup
GraphQL pilot at ING Investments
Follow me: @legkoletat

GraphQL pilot @ ING Investments

  • 1.
    GraphQL pilot at INGInvestments Mikhail Kuznetcov The Future of Web Technology @ Webdev Zwolle October 2019
  • 2.
    About me GraphQL pilotat ING Investments Mikhail Kuznetcov Developer at ING Investments Twitter: @legkoletat Github: github.com/shershen08 @legkoletat
  • 3.
    Agenda 1. GraphQL introduction 2.Pilot project at ING Investments GraphQL pilot at ING Investments @legkoletat
  • 4.
    What is GraphQLand how to use it 1. Introduction
  • 5.
    Overview ● A dataquery language specification ● Introduced by Facebook, open source 2015 ● Implemented in JavaScript, Perl, Python, Ruby, Java, C#, Scala, Go, PHP, etc GraphQL pilot at ING Investments Companies using GraphQL include: @legkoletat
  • 6.
    GraphQL pilot atING Investments @legkoletat
  • 7.
    Benefits of GraphQL ●Typed contract layer ● Several resources in single call ● Granular control over the data composition ● Arguments can be passed on any level of the request ● Versioning and documentation ● Solid ecosystem (GraphiQL, GraphQL Playground, eslint plugin, etc) GraphQL pilot at ING Investments @legkoletat
  • 8.
    Request example Results in GraphQLpilot at ING Investments @legkoletat
  • 9.
    Terminology GraphQL pilot atING Investments Types Queries Mutations Client: 1. Map variables to query 2. Do a POST call to API 3. Handle response(s) Server: ● Resolver functions ● Shared context data @legkoletat Subscriptions
  • 10.
    GraphQL types ● Int,Float, String, Boolean, ID ● Union types ● Lists ● Scalar types ● Non-Null markers ● __abc - system fields GraphQL pilot at ING Investments scalar Date enum MessageStatus { SENT VIEWED DELETED } type Picture { width: Int! height: Int! url: String status: MessageStatus } union Message = Text | Picture | Sound; type Chat { name: String! picture: Picture dateCreated: Date messages: [Message]! } /simple-messenger-schema.graphql @legkoletat
  • 11.
    GraphQL queries ● LikeGET in REST ● Name + Structure + Arguments ● Fragments ● @deffer for slow requests ● @deprecated and other annotations query { getUsers(first:2) { name groups { id, title ...latest Post } } } GraphQL pilot at ING Investments @legkoletat
  • 12.
    GraphQL mutations ● LikePOST/DELETE/PUT in REST ● Can return back the data mutation newUserMutation { UserCreate(firstName: "John", lastName: "Snow") { id isKing } } mutation DeleteUser { deleteUser(id: 1234) { dateCreated } } GraphQL pilot at ING Investments @legkoletat
  • 13.
    GraphQL tools GraphQL pilotat ING Investments @legkoletat
  • 14.
  • 15.
  • 16.
    Frontend ● Vanilla JS:a POST with JSON ● Apollo, Relay, framework-specific clients fetch('/graphql', { method: 'POST', body: JSON.stringify({ query: '{ products { code } }', variables: {} }), }) .then(res => res.json()) .then(res => console.log(res.data)); GraphQL pilot at ING Investments /index.html @legkoletat
  • 17.
    GraphQL at scale Schemastitching Apollo federation GraphQL pilot at ING Investments @legkoletat
  • 18.
    2. GraphQL inING Investments Details about pilot scope and implementation
  • 19.
    Motivation ● Code duplication ●Model inconsistencies ● Overfetching data GraphQL pilot at ING Investments @legkoletat
  • 20.
    Change: ● 1 callinstead of 2 ● 1 endpoint instead of 2 Query: query { instrumentDetails instrumentPriceHistory } Pilot page GraphQL pilot at ING Investments @legkoletat
  • 21.
  • 22.
    Frontend schema GraphQL pilotat ING Investments enum Period { ALL_TIME FIVE_YEARS ONE_DAY ... } enum RecommendationEnum { BUY HOLD ... } scalar OffsetDateTime type InstrumentDetails { closePriceValue: PriceValue currency: String currentPriceValue: PriceValue ... /src/schema.grapql @legkoletat
  • 23.
    Scalar types GraphQL pilotat ING Investments const AppNumberType = new GraphQLScalarType({ name: 'Number', parseValue(value) { //... return value; }, serialize(value) { //... return value; }, }); const typeResolvers = { BigDecimal: AppNumberType, Long: AppNumberType, // .. }; @legkoletat
  • 24.
    Frontend: mocking GraphQL pilotat ING Investments Node + expressJS $: npm start:with-mocks /api/path/ok.json /api/another-path/ok.json /gql.js const {makeExecutableSchema, addMockFunctionsToSchema} = require('graphql-tools'); const schema = makeExecutableSchema({ typeDefs, typeResolvers, }); addMockFunctionsToSchema({ schema, mocks, preserveResolvers: false, }); Frontend app /demo/mocks/.. @legkoletat
  • 25.
  • 26.
    Architecture ● Java Springmicroservices ● Experience service ● graphql-java lib GraphQL pilot at ING Investments Experience service Frontends Service A Service B Service C GraphQL REST REST @legkoletat
  • 27.
    Graphql-spqr ● Schema firstvs Code-first ● graphql-spqr provides code first approach ● Code-first => no *.grapql file in backend GraphQL pilot at ING Investments class UserService { @GraphQLQuery(name = "user") public User getById(@GraphQLArgument(name = "id") Integer id) { @legkoletat
  • 28.
    Errors @Data public class AppGraphQLErrorimplements GraphQLError { private String message; private int errorCode; private ErrorType errorType; private List<SourceLocation> locations; // ... } GraphQL pilot at ING Investments Map to custom error Feign service GraphQL: status 200 with “errors” property 401/403/500 HTTP Code @legkoletat
  • 29.
    Complexity calculation graphql: maxComplexity: 100 queryComplexities: instrumentDetails:20 instrumentPriceHistory: 60 GraphQL pilot at ING Investments Complexity check validator GraphQL endpoint Service layer Config FieldComplexityCalculator @legkoletat
  • 30.
  • 31.
    Pilot preliminary results GraphQLpilot at ING Investments ● User experience ● System complexity ● Developer experience @legkoletat
  • 32.
    Further challenges GraphQL pilotat ING Investments ● Adding mobile client ● Better tracing and logging ● Caching ● Possible Schema duplication ● Reuse of the REST services @legkoletat
  • 33.
  • 34.
    Share your feedback bit.ly/zwollemeetup GraphQLpilot at ING Investments Follow me: @legkoletat