Презентация подготовлена по материалам выступления Владислава Плясова на витебском MiniQ#23, который был проведен 27 февраля 2020 года:
https://communities.by/events/miniq-vitebsk-23 .
Про доклад:
Большинство нас слышало про такую технологию как GraphQL, но кто слышал про Apollo GraphQL Federation?
В своем докладе я бы хотел освятить следующие темы:
- GraphQL. Базовые понятия.
- Apollo Gateway. Что это за зверь и как им пользоваться. Проблема, которую он решает.
- Как создать свою "федерацию" из нескольких GraphQL сервисов.
- Какие плюшки предоставляет нам Apollo Gateway со старта.
- Ваши вопросы.
10. Основные задачи GraphQL
Унифицировать предоставляемые данные
Клиент сам решает, что он хочет видеть в ответе
Единая точка входа
Сократить количество запросов на сервер
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
}
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/