Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Apollo GraphQL Federation
Apollo GraphQL
Federation
Miniq #23
27 Февраля 2020
Немного о себе:
Плясов Владислав
- Разработчик в компании EPAM
- 2+ лет разработки на Java
- Пишу на GraphQL
План наших действий на сегодня:
План наших действий на сегодня:
Houston, we
don’t have
problems
I’m a tiger,
Rrrrrr
Your GraphQL
federation, Sir
++
План наших действий на сегодня:
Apollo
Gateway
+
ВОПРОС
GraphQL
INTRODUCTION
Что такое GraphQL?
?
?
?
?
Основные задачи GraphQL
Унифицировать предоставляемые данные
Клиент сам решает, что он хочет видеть в ответе
Единая точка входа
Сократить количество запросов на сервер
КОГДА
ИСПОЛЬЗОВАТЬ?
Facade pattern
System
Client side
UI
Server side
GraphQL
RESTful service 1 RESTful service 2
Database
Composite pattern
System
Client side
UI
Server side
GraphQL
RESTful serviceSQL RPC
С ЧЕГО НАЧАТЬ?
GraphQL Schema language
type QueryType {
get(params: Int!): String
}
schema {
query: QueryType
mutation: MutationType
}
type MutationType {
put(param: ID!): ID
}
scalar Date
type Types {
id: ID!
int: Int
float: Float
boolean: Boolean
string: String
array1: [String!]
array2: [String]!
scalarDate: Date
func(param: String): Int
}
?
GraphQL Schema language
interface BasicType {
id: ID!
int: Int
}
type Implementation implements BasicType {
id: ID!
int: Int
string: String
someFunction(param: String!): Int
}
GraphQL Schema language
GraphQL Schema language
type Obj {
id: ID!
fieldOne: Int
fieldTwo: String
}
input InputType {
fieldOne: Int
fieldTwo: String
}
type Mutation {
putObj(inputType: InputType): Obj
}
GraphQL Schema language
type TypeOne {
fieldOne: String
}
type TypeTwo {
fieldTwo: Int
}
union UnionType = TypeOne | TypeTwo
type Query {
search(params: Int!): UnionType
}
GraphQL Schema language
enum Enumeration {
A
B
C
}
type TypeOne {
id: ID!
field: Enumeration!
}
type Query {
request(param: Enumeration!): String
}
ЧТО ДАЛЬШЕ?
GraphQL REST Endpoint
{
"operationName": "{opName}",
"query": "{queryString}",
"variables": {
"variable": "variable"
}
}
Request body
Method: POST
Path: /graphql
GraphQL Function Resolvers
type Response {
id: ID!
method: String!
statusCode: Int!
message: String!
}
type Query {
getResponse(id: ID!): Response
getByMethod(method: String!): [Response]
}
GraphQL Function Resolvers
type Response {
id: ID!
method: String!
statusCode: Int!
message: String!
}
public class Response {
private Long id;
private String method;
private Integer statusCode;
private String message;
…
}
GraphQL Function Resolvers
getResponse(id: ID!): Response
public class QueryResolver {
…
public DataFetcher<Response> getResponse() {
return dataFetchingEnvironment -> {
String id = dataFetchingEnvironment.getArgument("id");
return responseService.get(id);
};
}
GraphQL Schema provider
public class SchemaProvider {
private GraphQL graphQL;
public GraphQL getGraphql() {
return graphQL;
}
private RuntimeWiring buildWiring() {
return RuntimeWiring.newRuntimeWiring()
.type(newTypeWiring("Query")
.dataFetcher("getResponse",
queryResolver.getResponse()))
.build();
}
…
}
GraphQL Schema provider
public class SchemaProvider {
private GraphQL graphQL;
public GraphQL getGraphql() {
return graphQL;
}
private void initGraphQLScheme() throws IOException {
Resource sdl = new ClassPathResource("schema.graphqls");
GraphQLSchema schema =
Federation.transform(sdl.getFile(), buildWiring())
.fetchEntities(dataFetchingEnvironment -> Collections.emptyList())
.resolveEntityType(typeResolutionEnvironment -> null)
.build();
graphQL = GraphQL.newGraphQL(schema).build();
}
…
}
КАК ДЕЛАТЬ
ЗАПРОСЫ?
GraphQL Query language
type Response {
id: ID!
method: String!
statusCode: Int!
message: String!
}
type Query {
getResponse(id: ID!): Response
getByMethod(method: String!): [Response]
}
GraphQL Query language
{
"errors": [],
"data": {
"getType": {
"id": 12,
"method": "POST"
}
}
}
Response body:
query GetResponse($id: ID!){
getResponse(id: $id) {
id
method
}
}
query string:
variables:
{
"id": 12
}
Application
Application layers (Java)
GraphQL
Services
Repositories REST Client
REST Endpoint
Application
Services
Repositories REST Client
REST Endpoints
GraphQL RESTful
GraphQL Resolvers
Apollo
GraphQL Federation
ВОПРОС
Проблема
1 N N 1
User Review Film
Проблема
Проблемы системы
Проблема N + 1 запросов
Пример: Вывести список фильмов с 1 отзывом
Производительность системы
Пропускная способность сети
Большое количество запросов на GraphQL сервисы
Клиент управляет процессом сбора данных
Требуется доп. логика в GraphQL сервисах
Apollo GraphQL Federation
Apollo GraphQL Federation
Немного терминов
Apollo GraphQL Federation – «микросервисная» система,
состоящая из нескольких GraphQL сервисов и Apollo Gateway
Apollo Gateway – backend-for-frontend приложение, которое
занимается обработкой GraphQL запросов и передачей их на
соответствующие GraphQL сервисы в федерации.
Apollo Federated Schema – Объединенные GraphQL схемы со
всех сервисов федерации в одну общую. Данная схема нужна
Apollo Gateway для обработки запросов.
Apollo
Federated Schema
Apollo Federated Schema
type Film @key(fields: "id") @extends {
id: ID! @external
reviews: [Review] @requires(fields: "id")
}
type Review @key(fields: "id") {
id: ID!
text: String!
user: User! @provides(fields: "name")
}
type User @key(fields: "id") {
id: ID! @external
name: String @external
reviews: [Review] @requires(fields: "id")
}
Review GraphQL serviceUser GraphQL service
type User {
id: ID!
name: String
rating: Float
}
type Film@key(fields: "id"){
id: ID!
name: name
}
type Query {
getFilm(
filmName: String): [Film]
}
Film GraphQL service
Apollo Federated Schema
type Film @key(fields: "id") @extends {
id: ID! @external
reviews: [Review] @requires(fields: "id")
}
type Review @key(fields: "id") {
id: ID!
text: String!
user: User! @provides(fields: "name")
}
type User @key(fields: "id") {
id: ID! @external
name: String @external
reviews: [Review] @requires(fields: "id")
}
Review GraphQL serviceUser GraphQL service
type User {
id: ID!
name: String
rating: Float
}
type Film@key(fields: "id"){
id: ID!
name: name
}
type Query {
getFilm(
filmName: String): [Film]
}
Film GraphQL service
@key(fields: "id")
@key – директива, обозначающая ключ/идентификатор GraphQL типа
(может быть вложенным и совмещенным).
Apollo Federated Schema
type Film @key(fields: "id") @extends {
id: ID! @external
reviews: [Review] @requires(fields: "id")
}
type Review @key(fields: "id") {
id: ID!
text: String!
user: User! @provides(fields: "name")
}
type User @key(fields: "id") {
id: ID! @external
name: String @external
reviews: [Review] @requires(fields: "id")
}
Review GraphQL serviceUser GraphQL service
type User {
id: ID!
name: String
rating: Float
}
type Film@key(fields: "id"){
id: ID!
name: name
}
type Query {
getFilm(
filmName: String): [Film]
}
Film GraphQL service
@extends
@extends/extend – директира/ключевое слово, которая обозначает,
что данный сервис расширяет указанный тип своим функционалом. Не
имеет связи с ключевым словом «implements».
type Film @key(fields: "id") @extends {
id: ID! @external
reviews: [Review] @requires(fields: "id")
}
type Review @key(fields: "id") {
id: ID!
text: String!
user: User! @provides(fields: "name")
}
type User @key(fields: "id") {
id: ID! @external
name: String @external
reviews: [Review] @requires(fields: "id")
}
Review GraphQL serviceUser GraphQL service
type User {
id: ID!
name: String
rating: Float
}
type Film@key(fields: "id"){
id: ID!
name: name
}
type Query {
getFilm(
filmName: String): [Film]
}
Film GraphQL service
@external
@external – директива, указывающая поля, которые предоставляются
другим сервисом в федерации.
Apollo Federated Schema
type Film @key(fields: "id") @extends {
id: ID! @external
reviews: [Review] @requires(fields: "id")
}
type Review @key(fields: "id") {
id: ID!
text: String!
user: User! @provides(fields: "name")
}
type User @key(fields: "id") {
id: ID! @external
name: String @external
reviews: [Review] @requires(fields: "id")
}
Review GraphQL serviceUser GraphQL service
type User {
id: ID!
name: String
rating: Float
}
type Film@key(fields: "id"){
id: ID!
name: name
}
type Query {
getFilm(
filmName: String): [Film]
}
Film GraphQL service
@requires(fields: "id")
@requires – обозначаем обязательные @external поля типа, которые
необходимо передать в запросе для выполнения функции.
Apollo Federated Schema
type Film @key(fields: "id") @extends {
id: ID! @external
reviews: [Review] @requires(fields: "id")
}
type Review @key(fields: "id") {
id: ID!
text: String!
user: User! @provides(fields: "name")
}
type User @key(fields: "id") {
id: ID! @external
name: String @external
reviews: [Review] @requires(fields: "id")
}
Review GraphQL serviceUser GraphQL service
type User {
id: ID!
name: String
rating: Float
}
type Film@key(fields: "id"){
id: ID!
name: name
}
type Query {
getFilm(
filmName: String): [Film]
}
Film GraphQL service
@provides(fields: "name")
@provides – директива, которая указывает набор @external полей,
которые сервис может предоставить внутри себя.
Apollo Federated Schema
Apollo
Gateway
Apollo Gateway
Apollo Gateway Features
Easy to create and deploy
Поддержка Persisted queries без доп. настроек
По средством использования @cacheControl директивы
Поддержка кэширования типов и полей
AWS API Gateway – AWS Lambda ( )– GraphQL Service
Возможность использовать как Serverless app.
Возможность интеграции с CDN сервисами для кэша
Автоматически распределяет запросы по сервисам
GraphQL Persisted Queries
Apollo
Gateway
GraphQL
Service
Apollo Federation CONs
Apollo Gateway поддерживает только NodeJS
Требует знание и понимание всей GraphQL схемы
Большое количество “issues” на GitHub (>200)
Интересные ссылки
GraphQL tutorial for Java:
https://www.graphql-java.com/documentation/v11/schema/
How to migrate to GraphQL from REST API:
https://blog.apimatic.io/moving-to-graphql-from-soap-or-rest-2383f7dc6523
GraphQL:
https://graphql.org/
Apollo GraphQL Federation example and GraphQL fast run:
https://github.com/vladislav1995?tab=repositories
Solve problem N+1 requests via DataLoaders:
https://github.com/graphql-java/java-dataloader#examples
Интересные ссылки
Apollo Gateway Caching:
https://www.apollographql.com/docs/apollo-server/performance/caching/
Apollo GraphQL Federation:
https://www.apollographql.com/docs/apollo-server/federation/core-
concepts/
Apollo Gateway request processing:
https://www.apollographql.com/docs/apollo-
server/federation/implementing/#customizing-outgoing-responses
How to deploy Apollo Gateway on AWS:
https://www.apollographql.com/docs/apollo-server/deployment/lambda/
СПАСИБО
ЗА
ВНИМАНИЕ
ВОПРОСЫ
И
ОТВЕТЫ

More Related Content

Apollo GraphQL Federation

  • 3. Немного о себе: Плясов Владислав - Разработчик в компании EPAM - 2+ лет разработки на Java - Пишу на GraphQL
  • 5. План наших действий на сегодня: Houston, we don’t have problems I’m a tiger, Rrrrrr Your GraphQL federation, Sir ++
  • 6. План наших действий на сегодня: Apollo Gateway +
  • 10. Основные задачи GraphQL Унифицировать предоставляемые данные Клиент сам решает, что он хочет видеть в ответе Единая точка входа Сократить количество запросов на сервер
  • 12. Facade pattern System Client side UI Server side GraphQL RESTful service 1 RESTful service 2 Database
  • 13. Composite pattern System Client side UI Server side GraphQL RESTful serviceSQL RPC
  • 15. GraphQL Schema language type QueryType { get(params: Int!): String } schema { query: QueryType mutation: MutationType } type MutationType { put(param: ID!): ID }
  • 16. scalar Date type Types { id: ID! int: Int float: Float boolean: Boolean string: String array1: [String!] array2: [String]! scalarDate: Date func(param: String): Int } ? GraphQL Schema language
  • 17. interface BasicType { id: ID! int: Int } type Implementation implements BasicType { id: ID! int: Int string: String someFunction(param: String!): Int } GraphQL Schema language
  • 18. GraphQL Schema language type Obj { id: ID! fieldOne: Int fieldTwo: String } input InputType { fieldOne: Int fieldTwo: String } type Mutation { putObj(inputType: InputType): Obj }
  • 19. GraphQL Schema language type TypeOne { fieldOne: String } type TypeTwo { fieldTwo: Int } union UnionType = TypeOne | TypeTwo type Query { search(params: Int!): UnionType }
  • 20. GraphQL Schema language enum Enumeration { A B C } type TypeOne { id: ID! field: Enumeration! } type Query { request(param: Enumeration!): String }
  • 22. GraphQL REST Endpoint { "operationName": "{opName}", "query": "{queryString}", "variables": { "variable": "variable" } } Request body Method: POST Path: /graphql
  • 23. GraphQL Function Resolvers type Response { id: ID! method: String! statusCode: Int! message: String! } type Query { getResponse(id: ID!): Response getByMethod(method: String!): [Response] }
  • 24. GraphQL Function Resolvers type Response { id: ID! method: String! statusCode: Int! message: String! } public class Response { private Long id; private String method; private Integer statusCode; private String message; … }
  • 25. GraphQL Function Resolvers getResponse(id: ID!): Response public class QueryResolver { … public DataFetcher<Response> getResponse() { return dataFetchingEnvironment -> { String id = dataFetchingEnvironment.getArgument("id"); return responseService.get(id); }; }
  • 26. GraphQL Schema provider public class SchemaProvider { private GraphQL graphQL; public GraphQL getGraphql() { return graphQL; } private RuntimeWiring buildWiring() { return RuntimeWiring.newRuntimeWiring() .type(newTypeWiring("Query") .dataFetcher("getResponse", queryResolver.getResponse())) .build(); } … }
  • 27. GraphQL Schema provider public class SchemaProvider { private GraphQL graphQL; public GraphQL getGraphql() { return graphQL; } private void initGraphQLScheme() throws IOException { Resource sdl = new ClassPathResource("schema.graphqls"); GraphQLSchema schema = Federation.transform(sdl.getFile(), buildWiring()) .fetchEntities(dataFetchingEnvironment -> Collections.emptyList()) .resolveEntityType(typeResolutionEnvironment -> null) .build(); graphQL = GraphQL.newGraphQL(schema).build(); } … }
  • 29. GraphQL Query language type Response { id: ID! method: String! statusCode: Int! message: String! } type Query { getResponse(id: ID!): Response getByMethod(method: String!): [Response] }
  • 30. GraphQL Query language { "errors": [], "data": { "getType": { "id": 12, "method": "POST" } } } Response body: query GetResponse($id: ID!){ getResponse(id: $id) { id method } } query string: variables: { "id": 12 }
  • 31. Application Application layers (Java) GraphQL Services Repositories REST Client REST Endpoint Application Services Repositories REST Client REST Endpoints GraphQL RESTful GraphQL Resolvers
  • 34. Проблема 1 N N 1 User Review Film
  • 36. Проблемы системы Проблема N + 1 запросов Пример: Вывести список фильмов с 1 отзывом Производительность системы Пропускная способность сети Большое количество запросов на GraphQL сервисы Клиент управляет процессом сбора данных Требуется доп. логика в GraphQL сервисах
  • 39. Немного терминов Apollo GraphQL Federation – «микросервисная» система, состоящая из нескольких GraphQL сервисов и Apollo Gateway Apollo Gateway – backend-for-frontend приложение, которое занимается обработкой GraphQL запросов и передачей их на соответствующие GraphQL сервисы в федерации. Apollo Federated Schema – Объединенные GraphQL схемы со всех сервисов федерации в одну общую. Данная схема нужна Apollo Gateway для обработки запросов.
  • 41. Apollo Federated Schema type Film @key(fields: "id") @extends { id: ID! @external reviews: [Review] @requires(fields: "id") } type Review @key(fields: "id") { id: ID! text: String! user: User! @provides(fields: "name") } type User @key(fields: "id") { id: ID! @external name: String @external reviews: [Review] @requires(fields: "id") } Review GraphQL serviceUser GraphQL service type User { id: ID! name: String rating: Float } type Film@key(fields: "id"){ id: ID! name: name } type Query { getFilm( filmName: String): [Film] } Film GraphQL service
  • 42. Apollo Federated Schema type Film @key(fields: "id") @extends { id: ID! @external reviews: [Review] @requires(fields: "id") } type Review @key(fields: "id") { id: ID! text: String! user: User! @provides(fields: "name") } type User @key(fields: "id") { id: ID! @external name: String @external reviews: [Review] @requires(fields: "id") } Review GraphQL serviceUser GraphQL service type User { id: ID! name: String rating: Float } type Film@key(fields: "id"){ id: ID! name: name } type Query { getFilm( filmName: String): [Film] } Film GraphQL service @key(fields: "id") @key – директива, обозначающая ключ/идентификатор GraphQL типа (может быть вложенным и совмещенным).
  • 43. Apollo Federated Schema type Film @key(fields: "id") @extends { id: ID! @external reviews: [Review] @requires(fields: "id") } type Review @key(fields: "id") { id: ID! text: String! user: User! @provides(fields: "name") } type User @key(fields: "id") { id: ID! @external name: String @external reviews: [Review] @requires(fields: "id") } Review GraphQL serviceUser GraphQL service type User { id: ID! name: String rating: Float } type Film@key(fields: "id"){ id: ID! name: name } type Query { getFilm( filmName: String): [Film] } Film GraphQL service @extends @extends/extend – директира/ключевое слово, которая обозначает, что данный сервис расширяет указанный тип своим функционалом. Не имеет связи с ключевым словом «implements».
  • 44. type Film @key(fields: "id") @extends { id: ID! @external reviews: [Review] @requires(fields: "id") } type Review @key(fields: "id") { id: ID! text: String! user: User! @provides(fields: "name") } type User @key(fields: "id") { id: ID! @external name: String @external reviews: [Review] @requires(fields: "id") } Review GraphQL serviceUser GraphQL service type User { id: ID! name: String rating: Float } type Film@key(fields: "id"){ id: ID! name: name } type Query { getFilm( filmName: String): [Film] } Film GraphQL service @external @external – директива, указывающая поля, которые предоставляются другим сервисом в федерации. Apollo Federated Schema
  • 45. type Film @key(fields: "id") @extends { id: ID! @external reviews: [Review] @requires(fields: "id") } type Review @key(fields: "id") { id: ID! text: String! user: User! @provides(fields: "name") } type User @key(fields: "id") { id: ID! @external name: String @external reviews: [Review] @requires(fields: "id") } Review GraphQL serviceUser GraphQL service type User { id: ID! name: String rating: Float } type Film@key(fields: "id"){ id: ID! name: name } type Query { getFilm( filmName: String): [Film] } Film GraphQL service @requires(fields: "id") @requires – обозначаем обязательные @external поля типа, которые необходимо передать в запросе для выполнения функции. Apollo Federated Schema
  • 46. type Film @key(fields: "id") @extends { id: ID! @external reviews: [Review] @requires(fields: "id") } type Review @key(fields: "id") { id: ID! text: String! user: User! @provides(fields: "name") } type User @key(fields: "id") { id: ID! @external name: String @external reviews: [Review] @requires(fields: "id") } Review GraphQL serviceUser GraphQL service type User { id: ID! name: String rating: Float } type Film@key(fields: "id"){ id: ID! name: name } type Query { getFilm( filmName: String): [Film] } Film GraphQL service @provides(fields: "name") @provides – директива, которая указывает набор @external полей, которые сервис может предоставить внутри себя. Apollo Federated Schema
  • 49. Apollo Gateway Features Easy to create and deploy Поддержка Persisted queries без доп. настроек По средством использования @cacheControl директивы Поддержка кэширования типов и полей AWS API Gateway – AWS Lambda ( )– GraphQL Service Возможность использовать как Serverless app. Возможность интеграции с CDN сервисами для кэша Автоматически распределяет запросы по сервисам
  • 51. Apollo Federation CONs Apollo Gateway поддерживает только NodeJS Требует знание и понимание всей GraphQL схемы Большое количество “issues” на GitHub (>200)
  • 52. Интересные ссылки GraphQL tutorial for Java: https://www.graphql-java.com/documentation/v11/schema/ How to migrate to GraphQL from REST API: https://blog.apimatic.io/moving-to-graphql-from-soap-or-rest-2383f7dc6523 GraphQL: https://graphql.org/ Apollo GraphQL Federation example and GraphQL fast run: https://github.com/vladislav1995?tab=repositories Solve problem N+1 requests via DataLoaders: https://github.com/graphql-java/java-dataloader#examples
  • 53. Интересные ссылки Apollo Gateway Caching: https://www.apollographql.com/docs/apollo-server/performance/caching/ Apollo GraphQL Federation: https://www.apollographql.com/docs/apollo-server/federation/core- concepts/ Apollo Gateway request processing: https://www.apollographql.com/docs/apollo- server/federation/implementing/#customizing-outgoing-responses How to deploy Apollo Gateway on AWS: https://www.apollographql.com/docs/apollo-server/deployment/lambda/