SlideShare a Scribd company logo
1 of 41
● Кіндріцький Максим
● 6 останніх років у Prom.ua (EVO)
● Team Lead команд User Engagement/Feedback Ecosystem
Привіт
Prom.ua
● Більше 50 тис. підприємців
● 3 млн. унікальних юзерів за добу
● Щодня більше ніж 70 тисяч покупок
● Python backend
● GraphQL > 7 років
● 10k rps на бекенди (моноліт + сервіси)
1. GraphQL + мікросервіси в Prom.ua
2. Проблеми розподіленого GraphQL на gRPC/REST
3. Як зробити розподілений GraphQL на Apollo Federation
4. Які плюси використання Apollo Federation
План
● Хто вже використовує GraphQL у себе в проекті
● Що робити з GraphQL якщо ви плануєте розділяти моноліт на сервіси
● Ви же маєте мікросервіси, але граф ще живе в моноліті
● Вас не влаштовує граф побудований на gRPC
● Ви лише плануєте впроваджувати GraphQL в мікросервіси
Кому це може бути цікаво?
GraphQL
● Мова запитів + рантайм(сервери написані на більшості популярних мов)
● Специфікація https://spec.graphql.org
● Python фреймворки
○ graphene
○ strawberry
○ ariadne
○ hiku
Що таке GraphQL ?
Що таке GraphQL ?
query GetUser {
user(id: 1) {
id
name
dateCreated
}
}
@strawberry.type
class User:
id: int
name: str
date_created: datetime
@strawberry.type
class Query:
@strawberry.field
def user(self, id: int) -> User | None:
return info.context.users.get(id)
GraphQL в Prom.ua
GraphQL + моноліт
User
Cabinet
Monolith
/graphql
GraphQL + моноліт
User
Cabinet
Monolith
/graphql
User
Cabinet
Monolith/
Products
/graphql
Opinions
Service
gRPC
GraphQL запит
query GetProduct {
product(id: 1) {
id
name
opinions {
id
rating
}
}
}
< grpc request
< database request
● Весь граф відгуків все ще знаходиться в моноліті
● Час на розробку фічей збільшився
● Час деплою все ще обмежений найповільнішим сервісом (моноліт)
● Трафік відгуків все ще проходить через моноліт
● Куча серіалізацій - json > dict > protobuf > dataclass > dict > json
● Знову over-fetching
Проблеми з якими ми зіткнулись
Serialize/deserialize pain
@dataclass
class Opinion:
id: int
date_created: datetime
def handle_request(body: str) -> str:
data = json.loads(body)
pb = api.get_opinion(data)
dcl = Opinion(id=pb.id, date_created=pb.date_created.ToDatetime())
result = db.to_dict()
return json.dumps(result)
Server over-fetching
query GetOpinion {
opinion(id: 1) {
id
dateCreated
}
}
message Opinion {
int32 id = 1;
string date_created = 2;
int32 user_id = 3;
...
int32 rating = 20;
}
Нам потрібно рішення яке дозволить:
● Перенести всі потрібні типи з моноліту в мікросервіс
● Зміни в типах і бізнес-логіці в мають бути лише в мікросервісі
● Прибрати частину трафіку з моноліту - щоб дані діставались з
потрібного сервісу
● Деплоїти зміни по нашим функціоналам незалежно від моноліту
● Деплоїти зміни значно швидше
Як вирішити всі ці проблеми ?
Apollo Federation
● З’являється gateway, який вирішує в який сервіс за даними сходити
● Щоб gateway знав про всі сервіси йому потрібна суперграф схема
● Отримати суперграф схему можна скомпозувавши схеми всіх сервісів
● Схема зберігається в GraphQL Registry, до якого gateway має доступ
Apollo Federation
Технологія, яка дозволяє композувати багато сервісів що мають графове
апі в одну велику схему - так званий суперграф.
Як це працює?
Стара архітектура
User
Cabinet
/graphql
Monolith/
Products
Opinions
Service
gRPC
Нова архітектура
User
Cabinet
Apollo
Router
/graphql
Monolith/
Products
Opinions
Service
/graphql
Graphql
Registry
● В сервісі відгуків з’являється /graphql апі і всі його типи тепер тут
○ Тепер типи належать мікросервісу
Що змінилось ?
● Роутер за даними про відгуки ходить в мікросервіс
○ Ми прибрали частину трафіку з моноліту
● Пишемо код і деплоїмо лише сервіс відгуків, моноліт не чіпаємо
○ Зміни по функціоналу відгуків деплояться незалежно від моноліту і це
швидко
● Роутер запитає в мікросервісу відгуків лише ті поля які запитав клієнт
○ Більше немає server over-fetching
● Кожен GraphQL сервіс це Apollo Federation Subgraph
● Всі сервіси пушають свою схему в GraphQL Registry
● GraphQL Registry будує supergraph схему
● Роутер стартує з supergraph схемою
● Всі запити проходять через роутер
Як це працює ?
Subgraph сервер
@strawberry.type
class Product:
id: int
name: str
@strawberry.type
class Query:
products: list[Product] = strawberry.federation.field(resolver=get_products)
schema = strawberry.federation.Schema(query=Query, enable_federation_v2=True)
Apollo Federation Entities
● Entities - це типи, що знаходяться в одному сервісі і можуть
використовуватися в інших сервісах
● Можна розширювати тип одного сервісу в іншому сервісі
GraphQL схема в моноліті
type Product {
id: Int!
name: String!
}
type Product {
id: Int!
name: String!
opinions: [Opinion!]!
}
GraphQL схема в сервісі відгуків
stub type
type Opinion {
id: Int!
rating: Int!
productId: Int!
}
type Product @key("id") {
id: Int!
opinions: [Opinion!]!
}
Код в моноліті
@strawberry.federation.type(keys=["id"])
class Product:
id: int
name: str
@classmethod
def resolve_reference(cls, id: strawberry.ID, info: Info):
product = info.context.products.get(int(id))
return Product(id=product.id, name=product.name)
Код в сервісі відгуків
@strawberry.type
class Opinion:
id: int
product_id: int
@strawberry.federation.type(keys=[“id”])
class Product:
id: int
@classmethod
def resolve_reference(cls, id: strawberry.ID, info: Info):
opinions = info.context.opinions.get_by_product(int(id))
return Product(id=id, opinions=opinions)
N+1 проблема
@strawberry.federation.type(keys=["id"])
class Product:
id: int
name: str
@classmethod
def resolve_reference(cls, id: strawberry.ID, info: Info):
product = info.context.products.get(int(id))
return Product(id=product.id, name=product.name)
Фікс N+1 в strawberry (dataloader)
def load_products(ids: list[int]) -> list[Product]:
return [Product(id=p.id, name=p.name) for p in products.list(ids)]
products_loader = DataLoader(load_products)
@strawberry.federation.type(keys=["id"])
class Product:
id: int
name: str
@classmethod
def resolve_reference(cls, id: strawberry.ID, info: Info):
return info.context.products_loader.load(int(id))
Фікс N+1 в hiku (by design)
product_fq = FieldsQuery("sqla.session", table=Product.__table__)
def resolve_product_reference(representations: list[dict]) -> list[int]:
return [r["id"] for r in representations]
FederatedNode(
"Product",
[Field("id", Integer, product_fq), Field("name", String, product_fq)],
directives=[Key("id")],
resolve_reference=resolve_product_reference,
)
GraphQL запит
query GetProduct {
product(id: 1) {
id
name
opinions {
id
rating
}
}
}
< data from opinion service
< data from product service
CI/CD та GraphQL Registry
Композиція схем сабграфів
● Apollo Rover - CLI tool
● GraphQL Registry + CI/CD
CI/CD
CI/CD
# strawberry export-schema reviews.graph:schema —output schema.graphql
# hive schema:publish —service reviews —url http://reviews.svc/graphql schema.graphql
GraphQL Registry
● Зберігає схеми
● Валідує схеми
● Композує схеми сабграфів у суперграф схему
● Дає апі для витягування схем (альтернатива інтроспекції на
продакшені)
Hive GraphQL Registry
Висновки
В результаті ми не просто вирішили наші проблеми, а і отримали навіть
деякі бенефіти:
● Ми стали релізити фічі швидше ніж при монолітній архітектурі
● Моноліту стало трошки легше, бо ми зняли з нього частину трафіку
● Менший асинхронний сервер + окрема менша база - функціонал
швидший
● В GraphQL Registry ми тепер можемо відслідковувати поля, що більше
не використовуються і видаляти їх безпечно
● Ми перевели декілька сервісів теж на Apollo Federation
Корисні посилання Apollo Federation
● Apollo Federation Spec - https://www.apollographql.com/docs/federation/
● Apollo Router - https://www.apollographql.com/docs/router
● Навчальні матеріали по Federation -
https://www.apollographql.com/tutorials/browse?categories=federation
● Hive GraphQL Registry - https://the-guild.dev/graphql/hive/docs
● How Netflix uses federation (big scale) -
https://www.infoq.com/presentations/netflix-scaling-graphql
Дякую

More Related Content

Similar to "Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi

iPhone Objective-C Development (ukr) (2009)
iPhone Objective-C Development (ukr) (2009)iPhone Objective-C Development (ukr) (2009)
iPhone Objective-C Development (ukr) (2009)Anatoliy Okhotnikov
 
"Incremental rollouts and rollbacks with business metrics control at every st...
"Incremental rollouts and rollbacks with business metrics control at every st..."Incremental rollouts and rollbacks with business metrics control at every st...
"Incremental rollouts and rollbacks with business metrics control at every st...Fwdays
 
Joomla 3. Що нового для розробників у новій версії - Віталій Маренков
Joomla 3. Що нового для розробників у новій версії - Віталій МаренковJoomla 3. Що нового для розробників у новій версії - Віталій Маренков
Joomla 3. Що нового для розробників у новій версії - Віталій МаренковIgor Bronovskyy
 
Global logic tech talk switching to Angular.js
Global logic tech talk switching to Angular.jsGlobal logic tech talk switching to Angular.js
Global logic tech talk switching to Angular.jsPavlo Iuriichuk
 
Павло Юрійчук — Перехід на Angular.js. Howto
Павло Юрійчук — Перехід на Angular.js. HowtoПавло Юрійчук — Перехід на Angular.js. Howto
Павло Юрійчук — Перехід на Angular.js. HowtoGlobalLogic Ukraine
 
Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...
Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...
Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...Lviv Startup Club
 
Using Metatags in Flex Developing
Using Metatags in Flex DevelopingUsing Metatags in Flex Developing
Using Metatags in Flex DevelopingRoman Shuper
 
"Rethinking Continuous Delivery", Andrii Nasinnyk
"Rethinking Continuous Delivery",  Andrii Nasinnyk"Rethinking Continuous Delivery",  Andrii Nasinnyk
"Rethinking Continuous Delivery", Andrii NasinnykFwdays
 
лаб. роб. №2 обєкти та сервіси що ними надаються
лаб. роб. №2   обєкти та сервіси що ними надаютьсялаб. роб. №2   обєкти та сервіси що ними надаються
лаб. роб. №2 обєкти та сервіси що ними надаютьсяcit-cit
 
[Knowledge Sharing] - Microservices Step-by-Step
[Knowledge Sharing] - Microservices Step-by-Step[Knowledge Sharing] - Microservices Step-by-Step
[Knowledge Sharing] - Microservices Step-by-StepExoft LLC
 
Play Mongodb
Play MongodbPlay Mongodb
Play MongodbInfinity
 
Борис Могила "Isomorphic React apps in production"
Борис Могила "Isomorphic React apps in production"Борис Могила "Isomorphic React apps in production"
Борис Могила "Isomorphic React apps in production"Fwdays
 
Основні поняття Android. Роман Мазур
Основні поняття Android. Роман МазурОсновні поняття Android. Роман Мазур
Основні поняття Android. Роман МазурStanfy
 

Similar to "Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi (20)

ASP.Net MVC
ASP.Net MVCASP.Net MVC
ASP.Net MVC
 
iPhone Objective-C Development (ukr) (2009)
iPhone Objective-C Development (ukr) (2009)iPhone Objective-C Development (ukr) (2009)
iPhone Objective-C Development (ukr) (2009)
 
Clean code (UA)
Clean code (UA)Clean code (UA)
Clean code (UA)
 
Design patterns part 2
Design patterns part 2Design patterns part 2
Design patterns part 2
 
Інші підсистеми
Інші підсистемиІнші підсистеми
Інші підсистеми
 
"Incremental rollouts and rollbacks with business metrics control at every st...
"Incremental rollouts and rollbacks with business metrics control at every st..."Incremental rollouts and rollbacks with business metrics control at every st...
"Incremental rollouts and rollbacks with business metrics control at every st...
 
Joomla 3. Що нового для розробників у новій версії - Віталій Маренков
Joomla 3. Що нового для розробників у новій версії - Віталій МаренковJoomla 3. Що нового для розробників у новій версії - Віталій Маренков
Joomla 3. Що нового для розробників у новій версії - Віталій Маренков
 
Global logic tech talk switching to Angular.js
Global logic tech talk switching to Angular.jsGlobal logic tech talk switching to Angular.js
Global logic tech talk switching to Angular.js
 
Павло Юрійчук — Перехід на Angular.js. Howto
Павло Юрійчук — Перехід на Angular.js. HowtoПавло Юрійчук — Перехід на Angular.js. Howto
Павло Юрійчук — Перехід на Angular.js. Howto
 
Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...
Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...
Alina Onyshchuk: Кейс реалізації забезпечення якості (QA) в digital агентстві...
 
Using Metatags in Flex Developing
Using Metatags in Flex DevelopingUsing Metatags in Flex Developing
Using Metatags in Flex Developing
 
L l13
L l13L l13
L l13
 
"Rethinking Continuous Delivery", Andrii Nasinnyk
"Rethinking Continuous Delivery",  Andrii Nasinnyk"Rethinking Continuous Delivery",  Andrii Nasinnyk
"Rethinking Continuous Delivery", Andrii Nasinnyk
 
Design patterns part 1
Design patterns part 1Design patterns part 1
Design patterns part 1
 
лаб. роб. №2 обєкти та сервіси що ними надаються
лаб. роб. №2   обєкти та сервіси що ними надаютьсялаб. роб. №2   обєкти та сервіси що ними надаються
лаб. роб. №2 обєкти та сервіси що ними надаються
 
[Knowledge Sharing] - Microservices Step-by-Step
[Knowledge Sharing] - Microservices Step-by-Step[Knowledge Sharing] - Microservices Step-by-Step
[Knowledge Sharing] - Microservices Step-by-Step
 
Play Mongodb
Play MongodbPlay Mongodb
Play Mongodb
 
Борис Могила "Isomorphic React apps in production"
Борис Могила "Isomorphic React apps in production"Борис Могила "Isomorphic React apps in production"
Борис Могила "Isomorphic React apps in production"
 
Основні поняття Android. Роман Мазур
Основні поняття Android. Роман МазурОсновні поняття Android. Роман Мазур
Основні поняття Android. Роман Мазур
 
Ddd
DddDdd
Ddd
 

More from Fwdays

"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y..."How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...Fwdays
 
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil TopchiiFwdays
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro Spodarets"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro SpodaretsFwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
"Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl..."Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl...Fwdays
 
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T..."How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...Fwdays
 
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ..."The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...Fwdays
 
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu..."[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...Fwdays
 
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care..."[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...Fwdays
 
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"..."4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...Fwdays
 
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast..."Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...Fwdays
 
"Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others..."Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others...Fwdays
 
"Mission (im) possible: How to get an offer in 2024?", Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?", Oleksandra MyronovaFwdays
 
"Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv..."Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv...Fwdays
 
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin..."How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...Fwdays
 
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy TytenkoFwdays
 

More from Fwdays (20)

"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y..."How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
"How Preply reduced ML model development time from 1 month to 1 day",Yevhen Y...
 
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
"GenAI Apps: Our Journey from Ideas to Production Excellence",Danil Topchii
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro Spodarets"What is a RAG system and how to build it",Dmytro Spodarets
"What is a RAG system and how to build it",Dmytro Spodarets
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
"Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl..."Rethinking the existing data loading and processing process as an ETL exampl...
"Rethinking the existing data loading and processing process as an ETL exampl...
 
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T..."How Ukrainian IT specialist can go on vacation abroad without crossing the T...
"How Ukrainian IT specialist can go on vacation abroad without crossing the T...
 
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ..."The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
"The Strength of Being Vulnerable: the experience from CIA, Tesla and Uber", ...
 
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu..."[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
"[QUICK TALK] Radical candor: how to achieve results faster thanks to a cultu...
 
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care..."[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
"[QUICK TALK] PDP Plan, the only one door to raise your salary and boost care...
 
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"..."4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
"4 horsemen of the apocalypse of working relationships (+ antidotes to them)"...
 
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast..."Reconnecting with Purpose: Rediscovering Job Interest after Burnout",  Anast...
"Reconnecting with Purpose: Rediscovering Job Interest after Burnout", Anast...
 
"Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others..."Mentoring 101: How to effectively invest experience in the success of others...
"Mentoring 101: How to effectively invest experience in the success of others...
 
"Mission (im) possible: How to get an offer in 2024?", Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova"Mission (im) possible: How to get an offer in 2024?",  Oleksandra Myronova
"Mission (im) possible: How to get an offer in 2024?", Oleksandra Myronova
 
"Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv..."Why have we learned how to package products, but not how to 'package ourselv...
"Why have we learned how to package products, but not how to 'package ourselv...
 
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin..."How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
"How to tame the dragon, or leadership with imposter syndrome", Oleksandr Zin...
 
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko"Leadership, Soft Skills, and Personality Types for IT teams",  Sergiy Tytenko
"Leadership, Soft Skills, and Personality Types for IT teams", Sergiy Tytenko
 

"Distributed graphs and microservices in Prom.ua", Maksym Kindritskyi

  • 1.
  • 2. ● Кіндріцький Максим ● 6 останніх років у Prom.ua (EVO) ● Team Lead команд User Engagement/Feedback Ecosystem Привіт
  • 3. Prom.ua ● Більше 50 тис. підприємців ● 3 млн. унікальних юзерів за добу ● Щодня більше ніж 70 тисяч покупок ● Python backend ● GraphQL > 7 років ● 10k rps на бекенди (моноліт + сервіси)
  • 4. 1. GraphQL + мікросервіси в Prom.ua 2. Проблеми розподіленого GraphQL на gRPC/REST 3. Як зробити розподілений GraphQL на Apollo Federation 4. Які плюси використання Apollo Federation План
  • 5. ● Хто вже використовує GraphQL у себе в проекті ● Що робити з GraphQL якщо ви плануєте розділяти моноліт на сервіси ● Ви же маєте мікросервіси, але граф ще живе в моноліті ● Вас не влаштовує граф побудований на gRPC ● Ви лише плануєте впроваджувати GraphQL в мікросервіси Кому це може бути цікаво?
  • 7. ● Мова запитів + рантайм(сервери написані на більшості популярних мов) ● Специфікація https://spec.graphql.org ● Python фреймворки ○ graphene ○ strawberry ○ ariadne ○ hiku Що таке GraphQL ?
  • 8. Що таке GraphQL ? query GetUser { user(id: 1) { id name dateCreated } } @strawberry.type class User: id: int name: str date_created: datetime @strawberry.type class Query: @strawberry.field def user(self, id: int) -> User | None: return info.context.users.get(id)
  • 12. GraphQL запит query GetProduct { product(id: 1) { id name opinions { id rating } } } < grpc request < database request
  • 13. ● Весь граф відгуків все ще знаходиться в моноліті ● Час на розробку фічей збільшився ● Час деплою все ще обмежений найповільнішим сервісом (моноліт) ● Трафік відгуків все ще проходить через моноліт ● Куча серіалізацій - json > dict > protobuf > dataclass > dict > json ● Знову over-fetching Проблеми з якими ми зіткнулись
  • 14. Serialize/deserialize pain @dataclass class Opinion: id: int date_created: datetime def handle_request(body: str) -> str: data = json.loads(body) pb = api.get_opinion(data) dcl = Opinion(id=pb.id, date_created=pb.date_created.ToDatetime()) result = db.to_dict() return json.dumps(result)
  • 15. Server over-fetching query GetOpinion { opinion(id: 1) { id dateCreated } } message Opinion { int32 id = 1; string date_created = 2; int32 user_id = 3; ... int32 rating = 20; }
  • 16. Нам потрібно рішення яке дозволить: ● Перенести всі потрібні типи з моноліту в мікросервіс ● Зміни в типах і бізнес-логіці в мають бути лише в мікросервісі ● Прибрати частину трафіку з моноліту - щоб дані діставались з потрібного сервісу ● Деплоїти зміни по нашим функціоналам незалежно від моноліту ● Деплоїти зміни значно швидше Як вирішити всі ці проблеми ?
  • 18. ● З’являється gateway, який вирішує в який сервіс за даними сходити ● Щоб gateway знав про всі сервіси йому потрібна суперграф схема ● Отримати суперграф схему можна скомпозувавши схеми всіх сервісів ● Схема зберігається в GraphQL Registry, до якого gateway має доступ Apollo Federation Технологія, яка дозволяє композувати багато сервісів що мають графове апі в одну велику схему - так званий суперграф. Як це працює?
  • 21. ● В сервісі відгуків з’являється /graphql апі і всі його типи тепер тут ○ Тепер типи належать мікросервісу Що змінилось ? ● Роутер за даними про відгуки ходить в мікросервіс ○ Ми прибрали частину трафіку з моноліту ● Пишемо код і деплоїмо лише сервіс відгуків, моноліт не чіпаємо ○ Зміни по функціоналу відгуків деплояться незалежно від моноліту і це швидко ● Роутер запитає в мікросервісу відгуків лише ті поля які запитав клієнт ○ Більше немає server over-fetching
  • 22. ● Кожен GraphQL сервіс це Apollo Federation Subgraph ● Всі сервіси пушають свою схему в GraphQL Registry ● GraphQL Registry будує supergraph схему ● Роутер стартує з supergraph схемою ● Всі запити проходять через роутер Як це працює ?
  • 23. Subgraph сервер @strawberry.type class Product: id: int name: str @strawberry.type class Query: products: list[Product] = strawberry.federation.field(resolver=get_products) schema = strawberry.federation.Schema(query=Query, enable_federation_v2=True)
  • 24. Apollo Federation Entities ● Entities - це типи, що знаходяться в одному сервісі і можуть використовуватися в інших сервісах ● Можна розширювати тип одного сервісу в іншому сервісі
  • 25. GraphQL схема в моноліті type Product { id: Int! name: String! } type Product { id: Int! name: String! opinions: [Opinion!]! }
  • 26. GraphQL схема в сервісі відгуків stub type type Opinion { id: Int! rating: Int! productId: Int! } type Product @key("id") { id: Int! opinions: [Opinion!]! }
  • 27. Код в моноліті @strawberry.federation.type(keys=["id"]) class Product: id: int name: str @classmethod def resolve_reference(cls, id: strawberry.ID, info: Info): product = info.context.products.get(int(id)) return Product(id=product.id, name=product.name)
  • 28. Код в сервісі відгуків @strawberry.type class Opinion: id: int product_id: int @strawberry.federation.type(keys=[“id”]) class Product: id: int @classmethod def resolve_reference(cls, id: strawberry.ID, info: Info): opinions = info.context.opinions.get_by_product(int(id)) return Product(id=id, opinions=opinions)
  • 29. N+1 проблема @strawberry.federation.type(keys=["id"]) class Product: id: int name: str @classmethod def resolve_reference(cls, id: strawberry.ID, info: Info): product = info.context.products.get(int(id)) return Product(id=product.id, name=product.name)
  • 30. Фікс N+1 в strawberry (dataloader) def load_products(ids: list[int]) -> list[Product]: return [Product(id=p.id, name=p.name) for p in products.list(ids)] products_loader = DataLoader(load_products) @strawberry.federation.type(keys=["id"]) class Product: id: int name: str @classmethod def resolve_reference(cls, id: strawberry.ID, info: Info): return info.context.products_loader.load(int(id))
  • 31. Фікс N+1 в hiku (by design) product_fq = FieldsQuery("sqla.session", table=Product.__table__) def resolve_product_reference(representations: list[dict]) -> list[int]: return [r["id"] for r in representations] FederatedNode( "Product", [Field("id", Integer, product_fq), Field("name", String, product_fq)], directives=[Key("id")], resolve_reference=resolve_product_reference, )
  • 32. GraphQL запит query GetProduct { product(id: 1) { id name opinions { id rating } } } < data from opinion service < data from product service
  • 33. CI/CD та GraphQL Registry
  • 34. Композиція схем сабграфів ● Apollo Rover - CLI tool ● GraphQL Registry + CI/CD
  • 35. CI/CD
  • 36. CI/CD # strawberry export-schema reviews.graph:schema —output schema.graphql # hive schema:publish —service reviews —url http://reviews.svc/graphql schema.graphql
  • 37. GraphQL Registry ● Зберігає схеми ● Валідує схеми ● Композує схеми сабграфів у суперграф схему ● Дає апі для витягування схем (альтернатива інтроспекції на продакшені)
  • 39. Висновки В результаті ми не просто вирішили наші проблеми, а і отримали навіть деякі бенефіти: ● Ми стали релізити фічі швидше ніж при монолітній архітектурі ● Моноліту стало трошки легше, бо ми зняли з нього частину трафіку ● Менший асинхронний сервер + окрема менша база - функціонал швидший ● В GraphQL Registry ми тепер можемо відслідковувати поля, що більше не використовуються і видаляти їх безпечно ● Ми перевели декілька сервісів теж на Apollo Federation
  • 40. Корисні посилання Apollo Federation ● Apollo Federation Spec - https://www.apollographql.com/docs/federation/ ● Apollo Router - https://www.apollographql.com/docs/router ● Навчальні матеріали по Federation - https://www.apollographql.com/tutorials/browse?categories=federation ● Hive GraphQL Registry - https://the-guild.dev/graphql/hive/docs ● How Netflix uses federation (big scale) - https://www.infoq.com/presentations/netflix-scaling-graphql