Service-oriented
GraphQL
Nick Raienko, Svitla
• Web Service Architecture
• Unified Query Language for your data
• Real-time
• Decomposition of your Monolith Architecture
• Easy switch between datastores
Imagine you need…
• Web Service Architecture
• Unified Query Language for your data
• Real-time
• Decomposition of your Monolith Architecture
• Easy switch between datastores
Web Service Architecture
• W3C Working Group Note 11 (w3.org/TR/ws-arch)
• Defined in 2004
Service Oriented Model :(
• Web Service Architecture
• Unified Query Language for your data
• Real-time
• Decomposition of your Monolith Architecture
• Easy switch between datastores
REST
• Client-server
• Usage of stateless operations
• HTTP for communication
• URI as string to represent desired resource
• Cacheable and Layered
REST
• No spec
• No protocol
• No query language
• No real-time
REST if you are Backend Developer
const UserList = require('../controllers/userListController');
app.route('/users')
.get(UserList.listUsers)
.post(UserList.createUser);
app.route('/user/:userId')
.get(UserList.getUser)
.put(UserList.updateUser)
.delete(UserList.deleteUser);
REST if you are Frontend Developer
async function getUser(id) {
try {
const response =
await fetch(`https://blabla.io/user/${id}`);
const json = await response.json();
return json.user;
} catch(error) {
console.error(error);
}
}
REST if you are Roy Fielding
What will be the response?
'/user/42'
Perhaps
{
“user": {
"id": "42",
"firstName": "Eric",
"lastName": "Cartman",
"userName": "notfat"
}
}
Left keys only
{
“user": {
"id": "42",
"firstName": "Eric",
"lastName": "Cartman",
"userName": "notfat"
}
}
Add argument
{
“user(id: 42)“: {
"id": "42",
"firstName": "Eric",
"lastName": "Cartman",
"userName": "notfat"
}
}
GraphQL Query
{
user(id: 42) {
id
firstName
lastName
userName
}
}
GraphQL Mutation
mutation {
createUser(
firstName: “Stan”
lastName: “Marsh”
userName: “stan”
) {
id
firstName
lastName
userName
}
}
Thats everything about GraphQL except
Field Aliases
Fragments
Types System
Type
Conditions
Directives
Validation
Interfaces
Inputs
Unions
Enums
Lists
Introspection
Variables
Subscriptions
Errors
Real-time here
Field Aliases
Fragments
Types System
Type
Conditions
Directives
Validation
Interfaces
Inputs
Unions
Enums
Lists
Introspection
Variables
Subscriptions
Errors
• Web Service Architecture
• Unified Query Language for your data
• Real-time
• Decomposition of your Monolith Architecture
• Easy switch between datastores
Subscription
• A long‐lived request that fetches data in response
to source events
• The result is an event stream
• “Pub‐Sub” system may produce an event stream
• Subscriptions, by contrast, are stateful
GraphQL Subscription
subscription NewMessages {
newMessage(roomId: 123) {
user
text
}
}
• Unified Query Language
• RFC Draft Specification
• Supports Real-time stateful interaction
• graphql-js reference implementation
• express-graphql server
• GraphiQL console
• A community building tools for GraphQL
• Significant work on Subscriptions
• Integration with Hapi, Koa, Meteor, AWS Lambda
• Web client for React, Angular, Vanilla JS
• Mobile client for native iOS and Android
• Authentication support
GraphQL Example
const userType = new GraphQLObjectType({
name: 'User',
description: ‘User profile.’,
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'The id of the user.',
},
username: {
type: GraphQLString,
description: 'The name of the user.',
},
firstName: {
type: GraphQLString,
description: 'The first name of the user.',
},
lastName: {
type: GraphQLString,
description: 'The last name of the user.',
},
}),
});
const queryType = new GraphQLObjectType({
name: 'Query',
fields: () => ({
users: {
type: userType,
args: {
id: {
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: (root, { id }) => getUser(id),
},
})
});
User Type Query Type
GraphQL Schema
# User profile.
type User {
# The id of the user.
id: String!
# The name of the user.
name: String
# The first name of the user.
userName: String
# The last name of the user.
firstName: String
}
User Type Query Type
type Query {
users(id: String!): User
}
GraphQL Resolver
const resolverMap = {
Query: {
users(obj, args, context, info) => getUser(args.id),
},
};
Apollo Architecture
DB
Model
Resolver
Schema
API Cache
Client
Apollo Resolver
• Data fetching
• Business logic
• Authorization and Authentication
• Permission rules
• Interface to third-party API
• Caching
• Web Service Architecture
• Unified Query Language for your data
• Real-time
• Decomposition of your Monolith Architecture
• Easy switch between datastores
• Provide RESTful and Real-Time API
• Service-oriented Architecture
• Datastore Agnostic
• Outstanding Authentication and Permission System
• Client for React, React Native, Angular, Vue
• Scaffolding
Feathers Service
export default function() {
const app = this;
const Model = createModel(app);
const options = {
name: 'users',
Model,
};
/* Initialize our service with any options it requires */
app.use('/users', createService(options));
/* Get our initialized service so that we can register hooks and filters */
const service = app.service('users');
service.hooks(hooks);
if (service.filter) {
service.filter(filters);
}
};
Feathers Hook
export default {
before: {
all: [],
find: [ authenticate('jwt') ],
get: [ authenticate('jwt') ],
create: [hashPassword() ],
update: [ authenticate('jwt') ],
patch: [ authenticate('jwt') ],
remove: [ authenticate('jwt') ]
},
after: {
all: [commonHooks.when(
hook => hook.params.provider,
commonHooks.discard(‘password’)
)],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
};
• Web Service Architecture
• Unified Query Language for your data
• Real-time
• Decomposition of your Monolith Architecture
• Easy switch between datastores
DB
Model
Hook
Service
Model
Hook
Service
Model
Hook
Service
Client
Feathers Architecture
DB
Model
Hook
Service
Model
Hook
Service
Model
Resolver
Schema
Client
Service-Oriented GraphQL
• Web Service Architecture
• Unified Query Language for your data
• Real-time
• Decomposition of your Monolith Architecture
• Easy switch between datastores
Service-Oriented GraphQL
P.S.
Here be Microservices

Nick Raienko ''Service-oriented GraphQL''

  • 1.
  • 2.
    • Web ServiceArchitecture • Unified Query Language for your data • Real-time • Decomposition of your Monolith Architecture • Easy switch between datastores Imagine you need…
  • 3.
    • Web ServiceArchitecture • Unified Query Language for your data • Real-time • Decomposition of your Monolith Architecture • Easy switch between datastores
  • 4.
    Web Service Architecture •W3C Working Group Note 11 (w3.org/TR/ws-arch) • Defined in 2004
  • 5.
  • 6.
    • Web ServiceArchitecture • Unified Query Language for your data • Real-time • Decomposition of your Monolith Architecture • Easy switch between datastores
  • 9.
    REST • Client-server • Usageof stateless operations • HTTP for communication • URI as string to represent desired resource • Cacheable and Layered
  • 10.
    REST • No spec •No protocol • No query language • No real-time
  • 11.
    REST if youare Backend Developer const UserList = require('../controllers/userListController'); app.route('/users') .get(UserList.listUsers) .post(UserList.createUser); app.route('/user/:userId') .get(UserList.getUser) .put(UserList.updateUser) .delete(UserList.deleteUser);
  • 12.
    REST if youare Frontend Developer async function getUser(id) { try { const response = await fetch(`https://blabla.io/user/${id}`); const json = await response.json(); return json.user; } catch(error) { console.error(error); } }
  • 13.
    REST if youare Roy Fielding
  • 14.
    What will bethe response? '/user/42'
  • 15.
    Perhaps { “user": { "id": "42", "firstName":"Eric", "lastName": "Cartman", "userName": "notfat" } }
  • 16.
    Left keys only { “user":{ "id": "42", "firstName": "Eric", "lastName": "Cartman", "userName": "notfat" } }
  • 17.
    Add argument { “user(id: 42)“:{ "id": "42", "firstName": "Eric", "lastName": "Cartman", "userName": "notfat" } }
  • 18.
    GraphQL Query { user(id: 42){ id firstName lastName userName } }
  • 19.
    GraphQL Mutation mutation { createUser( firstName:“Stan” lastName: “Marsh” userName: “stan” ) { id firstName lastName userName } }
  • 20.
    Thats everything aboutGraphQL except Field Aliases Fragments Types System Type Conditions Directives Validation Interfaces Inputs Unions Enums Lists Introspection Variables Subscriptions Errors
  • 21.
    Real-time here Field Aliases Fragments TypesSystem Type Conditions Directives Validation Interfaces Inputs Unions Enums Lists Introspection Variables Subscriptions Errors
  • 22.
    • Web ServiceArchitecture • Unified Query Language for your data • Real-time • Decomposition of your Monolith Architecture • Easy switch between datastores
  • 23.
    Subscription • A long‐livedrequest that fetches data in response to source events • The result is an event stream • “Pub‐Sub” system may produce an event stream • Subscriptions, by contrast, are stateful
  • 24.
    GraphQL Subscription subscription NewMessages{ newMessage(roomId: 123) { user text } }
  • 26.
    • Unified QueryLanguage • RFC Draft Specification • Supports Real-time stateful interaction • graphql-js reference implementation • express-graphql server • GraphiQL console
  • 28.
    • A communitybuilding tools for GraphQL • Significant work on Subscriptions • Integration with Hapi, Koa, Meteor, AWS Lambda • Web client for React, Angular, Vanilla JS • Mobile client for native iOS and Android • Authentication support
  • 29.
    GraphQL Example const userType= new GraphQLObjectType({ name: 'User', description: ‘User profile.’, fields: () => ({ id: { type: new GraphQLNonNull(GraphQLString), description: 'The id of the user.', }, username: { type: GraphQLString, description: 'The name of the user.', }, firstName: { type: GraphQLString, description: 'The first name of the user.', }, lastName: { type: GraphQLString, description: 'The last name of the user.', }, }), }); const queryType = new GraphQLObjectType({ name: 'Query', fields: () => ({ users: { type: userType, args: { id: { type: new GraphQLNonNull(GraphQLString) } }, resolve: (root, { id }) => getUser(id), }, }) }); User Type Query Type
  • 30.
    GraphQL Schema # Userprofile. type User { # The id of the user. id: String! # The name of the user. name: String # The first name of the user. userName: String # The last name of the user. firstName: String } User Type Query Type type Query { users(id: String!): User }
  • 31.
    GraphQL Resolver const resolverMap= { Query: { users(obj, args, context, info) => getUser(args.id), }, };
  • 32.
  • 33.
    Apollo Resolver • Datafetching • Business logic • Authorization and Authentication • Permission rules • Interface to third-party API • Caching
  • 34.
    • Web ServiceArchitecture • Unified Query Language for your data • Real-time • Decomposition of your Monolith Architecture • Easy switch between datastores
  • 35.
    • Provide RESTfuland Real-Time API • Service-oriented Architecture • Datastore Agnostic • Outstanding Authentication and Permission System • Client for React, React Native, Angular, Vue • Scaffolding
  • 36.
    Feathers Service export defaultfunction() { const app = this; const Model = createModel(app); const options = { name: 'users', Model, }; /* Initialize our service with any options it requires */ app.use('/users', createService(options)); /* Get our initialized service so that we can register hooks and filters */ const service = app.service('users'); service.hooks(hooks); if (service.filter) { service.filter(filters); } };
  • 37.
    Feathers Hook export default{ before: { all: [], find: [ authenticate('jwt') ], get: [ authenticate('jwt') ], create: [hashPassword() ], update: [ authenticate('jwt') ], patch: [ authenticate('jwt') ], remove: [ authenticate('jwt') ] }, after: { all: [commonHooks.when( hook => hook.params.provider, commonHooks.discard(‘password’) )], find: [], get: [], create: [], update: [], patch: [], remove: [] }, };
  • 38.
    • Web ServiceArchitecture • Unified Query Language for your data • Real-time • Decomposition of your Monolith Architecture • Easy switch between datastores
  • 40.
  • 41.
  • 42.
    • Web ServiceArchitecture • Unified Query Language for your data • Real-time • Decomposition of your Monolith Architecture • Easy switch between datastores Service-Oriented GraphQL
  • 43.