Переход от REST API к GraphQL на примере реальных проектов презентация

Содержание

Слайд 2

Антон Морев Приложения Сайты Системы автоматизации (CRM, ERP) Маркетинг Сопровождение

Антон Морев

Приложения
Сайты
Системы автоматизации (CRM, ERP)
Маркетинг
Сопровождение проектов
IT-Директор
Оптимизация процессов разработки
Review ключевых проектов

Слайд 3

DATABASE CACHE OTHER API QUEUE … ETC КЛИЕНТ СЕРВЕР Взаимодействие с сервером API

DATABASE

CACHE

OTHER API

QUEUE

… ETC

КЛИЕНТ

СЕРВЕР

Взаимодействие с сервером

API

Слайд 4

POST /order GET /goods Стандартное решение на REST

POST /order

GET /goods

Стандартное решение на REST

Слайд 5

ДОКУМЕНТАЦИЯ

ДОКУМЕНТАЦИЯ

Слайд 6

“Я не хочу писать документацию, я хочу писать код” © “Senior” Developer №1 БЕЛЫЙ ЛИСТ

“Я не хочу писать документацию,
я хочу писать код”
© “Senior” Developer

№1

БЕЛЫЙ

ЛИСТ
Слайд 7

спроси у Ивана - он знает где у нас это

спроси у Ивана - он знает где у нас это

в каком

поле у нас текущий статус?

№2

№2

МУДРЕЦ

Слайд 8

«Мы храним документацию в docx файлах под git со всеми

«Мы храним документацию в docx файлах под git
со всеми JSON

ответами и запросами»

№3

WORD, EXСEL , GOOGLEDOC

Слайд 9

Инструменты для документации (swagger и тд) №4

Инструменты для документации (swagger и тд)

№4

Слайд 10

РАЗГРАНИЧЕНИЕ ДАННЫХ

РАЗГРАНИЧЕНИЕ ДАННЫХ

Слайд 11

Количество запросов HEADER FOOTER PRODUCT CARD REVIEWS getDeliveryData getHeaderData getFooterData getProductCardData getReviewsData CONNECTED PRODUCTS

Количество запросов

HEADER

FOOTER

PRODUCT CARD

REVIEWS

getDeliveryData

getHeaderData

getFooterData

getProductCardData

getReviewsData

CONNECTED PRODUCTS

Слайд 12

КАТАЛОГ ТОВАРОВ ОТЗЫВЫ КОРЗИНА КАРТОЧКА ТОВАРА ИСТОРИЯ ЗАКАЗОВ ТОВАР

КАТАЛОГ ТОВАРОВ

ОТЗЫВЫ

КОРЗИНА

КАРТОЧКА ТОВАРА

ИСТОРИЯ ЗАКАЗОВ

ТОВАР

Слайд 13

{ "id": 123, "title": "Bentley For Men", "price": 100, "connectedProducts":

{
"id": 123,
"title": "Bentley For Men",
"price": 100,

"connectedProducts": [],

"photos": [],
"countInBasket": 3,

"reviews": [],
"variants": []
}

"description": "Лучшие духи",
"brand": "Bentley",

GET /allRoundProduct?id=123

Слайд 14

СВОЯ МОДЕЛЬ НА КАЖДУЮ СИТУАЦИЮ

СВОЯ МОДЕЛЬ НА КАЖДУЮ СИТУАЦИЮ

Слайд 15

{ "id": 123, "title": "", "price": "", "description": "", "brand": "", "photos": [] } GET /product/card?id=123

{
"id": 123,
"title": "",
"price": "",
"description": "",
"brand": "",

"photos": []
}

GET /product/card?id=123

Слайд 16

[ { "id": 123, "title": "", "price": 100, "photo": {} } ] GET /product/connected?id=123

[
{
"id": 123,
"title": "",
"price": 100,
"photo": {}
}
]

GET

/product/connected?id=123
Слайд 17

[ { "id": 123, "title": "", "photo": [], "rating": 3, "price": 100 } ] GET /product/list

[
{
"id": 123,
"title": "",
"photo": [],
"rating": 3,

"price": 100
}
]

GET /product/list

Слайд 18

{ "commonInfo": {}, "cardInfo": {}, "listInfo": {}, "basketInfo": {} } ИЕРАРХИЧЕСКАЯ МОДЕЛЬ GET /product/full?id=123

{
"commonInfo": {},
"cardInfo": {},
"listInfo": {},
"basketInfo": {}
}

ИЕРАРХИЧЕСКАЯ МОДЕЛЬ

GET /product/full?id=123

Слайд 19

Интернет-магазин Решения на REST ЯЗЫК ЗАПРОСОВ только cardInfo и basketInfo product/full?id=1&fields=cardInfo,basketInfo API Интернет-магазин. Решения на REST

Интернет-магазин Решения на REST

ЯЗЫК ЗАПРОСОВ

только cardInfo и basketInfo

product/full?id=1&fields=cardInfo,basketInfo

API

Интернет-магазин. Решения на REST

Слайд 20

getModel?id=1&fields=title, description,price getModel?id=1&fields=title,price, connectedProducts.title, connectedProducts.description getModel?id=1&fields= user.id,reviews.date,reviews.text, title,description, rating,price, reviews.user.name,reviews. connectedProducts.title, connectedProducts.price, connectedProducts.rating, photos.src,photos.alt, dicsount.rate,discount.amount

getModel?id=1&fields=title,
description,price

getModel?id=1&fields=title,price,
connectedProducts.title,
connectedProducts.description

getModel?id=1&fields=

user.id,reviews.date,reviews.text,

title,description,

rating,price,

reviews.user.name,reviews.

connectedProducts.title,
connectedProducts.price, connectedProducts.rating,

photos.src,photos.alt,

dicsount.rate,discount.amount

Слайд 21

МНОГО ЗАПРОСОВ (удобно) ОДИН ЗАПРОС (неудобно) Интернет-магазин. Решения на REST

МНОГО
ЗАПРОСОВ
(удобно)

ОДИН
ЗАПРОС
(неудобно)

Интернет-магазин. Решения на REST

Слайд 22

Можно выбирать что именно мы хотим получить Несколько сущностей в

Можно выбирать что именно мы хотим получить

Несколько сущностей в одном запросе

Автоматическая

документация

Интернет-магазин Желаемое решение

Интернет магазин. Желаемое решение

Слайд 23

РЕАЛИЗАЦИЯ НА GRAPHQL

РЕАЛИЗАЦИЯ НА GRAPHQL

Слайд 24

ОПИСАНИЕ СХЕМЫ type Product { id: ID! title: String description:

ОПИСАНИЕ СХЕМЫ
type Product {
id: ID!

title: String
description: String
}

type Query

{
product (id: ID!): Product
}
Слайд 25

ЗАПРОС query { product (id: 123) { title description } }

ЗАПРОС

query {
product (id: 123) {
title
description
}
}

Слайд 26

{ "product": { "title": "Духи", "description":"Описание товара…" } } ОТВЕТ

{
"product": {
"title": "Духи",
"description":"Описание товара…"
}
}

ОТВЕТ

Слайд 27

type Product { id: ID title: String description: String variants: [ProductVariant] } ВАРИАНТЫ ТОВАРА

type Product {
id: ID
title: String
description: String
variants: [ProductVariant]
}

ВАРИАНТЫ

ТОВАРА
Слайд 28

query { product (id: 123) { title variants { id

query {
product (id: 123) {
title
variants {
id
title
}
}
}

ПОЛУЧЕНИЯ ПОЛЯ

VARIANTS
Слайд 29

{ "title": "Chanel Chance Eau Tendre", "variants": [ { "id":

{
"title": "Chanel Chance Eau Tendre",
"variants": [
{
"id": 1,

"title": "Подарок, 200мл"
},
{
"id": 2,
"title": "Пробник, 1.5мл "
}
]
}

ОТВЕТ

Слайд 30

type ProductVariant { id: ID title: String price: Float priceDiscount:

type ProductVariant {
id: ID
title: String
price: Float
priceDiscount: Float

image: ImageModel
}

ИНТЕРНЕТ-МАГАЗИН РЕШЕНИЯ НА GRAPHQL

Слайд 31

ЗАПРОС ДЛЯ СТРАНИЦЫ query { header { #header fields }

ЗАПРОС ДЛЯ СТРАНИЦЫ

query {
header {
#header fields
}
product (id:

123) {
#product fields
}
footer {
#footer fields
}
}
Слайд 32

Слайд 33

Выбор/Создание запроса Добавление нужного поля в response Реализация логики получения

Выбор/Создание запроса

Добавление нужного
поля в response

Реализация логики
получения поля

Расширение документации

BACKEND ДО

Процесс внедрения

нового свойства в сущность товара
Слайд 34

BACKEND ПОСЛЕ Процесс внедрения нового свойства в сущность товара Выбор/Создание

BACKEND ПОСЛЕ

Процесс внедрения нового свойства в сущность товара

Выбор/Создание запроса

Добавление нужного
поля в

тип

Реализация логики
получения поля

Расширение документации

Процесс внедрения нового свойства в сущность товара

Слайд 35

FRONTEND ДО Внедрение GraphQL Интернет-магазин Выяснение в каком запросе было

FRONTEND ДО

Внедрение GraphQL Интернет-магазин

Выяснение в каком запросе было обновление

Изучение документации

Использование поля

Новый

endpoint/расширение старого

Процесс внедрения нового свойства в сущность товара

Слайд 36

FRONTEND ПОСЛЕ Добавление нужного поля в GQL запрос за сущностью

FRONTEND ПОСЛЕ

Добавление нужного поля в GQL запрос за сущностью

Изучение документации

Использование поля

Новый

endpoint/расширение старого

Процесс внедрения нового свойства в сущность товара

Слайд 37

ВНЕДРЕНИЕ GRAPHQL РАЗРАБОТКА С МИКРОСЕРВИСАМИ

ВНЕДРЕНИЕ GRAPHQL РАЗРАБОТКА С МИКРОСЕРВИСАМИ

Слайд 38

Банк криптовалюты Интерфейс КРИПТОВАЛЮТНЫЕ БИРЖИ WALLET RPC ЯДРО СИСТЕМЫ

Банк криптовалюты

Интерфейс

КРИПТОВАЛЮТНЫЕ БИРЖИ

WALLET RPC

ЯДРО СИСТЕМЫ

Слайд 39

PHP Yii2 REST API Module Wallet RPC (C++) Exchange API


PHP Yii2

REST

API Module

Wallet RPC (C++)

Exchange API

Auth module

Deposit module

Payments module

Email module

ИНТЕРФЕЙС

Слайд 40

class TransactionsController extends Controller { public function actionIndex($page = 1,

class TransactionsController extends Controller
{
public function actionIndex($page = 1, $type =

null)
{
$userId = Yii::$app->user->id;
return $this->transactionsRepository
->getTransactions($userId, $page, $type);
}
}
Слайд 41

Интерфейс Email service (GoLang) Money module (PHP) Exchanges Services (PHP,

Интерфейс

Email service (GoLang)

Money module
(PHP)

Exchanges Services
(PHP, NodeJS)

Chat service
(NodeJS)

API Core Server (PHP Yii2)

Docs

Docs

Docs

Docs

Слайд 42

СОБСТВЕННЫЙ РЕПОЗИТОРИЙ ПРЯМОЙ ЗАПРОС В БД 'resolve' => function($value, $args,

СОБСТВЕННЫЙ РЕПОЗИТОРИЙ

ПРЯМОЙ ЗАПРОС В БД

'resolve' => function($value, $args, $context, ResolveInfo $info)

{
return DB::getInstance()->select('SELECT * from products');
},

'resolve' => function($value, $args, $context, ResolveInfo $info) {
//Получение любой информации
}

'resolve' => function($value, $args, $context, ResolveInfo $info) {
return $context->productRepository->getProducts($args['page']);
}

Слайд 43

GET query { /user/ payments /list user { payments {

GET

query {

/user/

payments

/list

user {

payments {

list {

id
amount
}
}

}
}
Слайд 44

GET /notifications /user /payments /list GET /user /info GET /user

GET

/notifications

/user

/payments

/list

GET

/user

/info

GET

/user

GET

/user

/system

/status

/list

query {

user {

payments {

list {

id
amount
}
}

info

{
name
money
}

system {

status

list {

}
notifications {

text
}
}
}
}

id

Слайд 45

ВНЕДРЕНИЕ GRAPHQL ОПТИМИЗАЦИЯ РАЗРАБОТКИ

ВНЕДРЕНИЕ GRAPHQL ОПТИМИЗАЦИЯ РАЗРАБОТКИ

Слайд 46

сущности сбор данных с API сервера управление примитивными CRUD сущностями

сущности

сбор данных с API сервера

управление примитивными CRUD сущностями

Внедрение GraphQL. Админ-панель

SITE

API Server

Admin

Panel

отображение данных
Frontend логика

бизнес логика
обработка заявок
система оповещений

управления бизнес логикой (формы)

Слайд 47

Внедрение GraphQL. Админ-панель Описание сущности GraphQL схема resolvers для каждого поля каждой сущности интерфейс админ-панели автоформирование

Внедрение GraphQL. Админ-панель

Описание сущности

GraphQL схема
resolvers для каждого поля каждой сущности
интерфейс админ-панели

автоформирование

Слайд 48

{ “type”: “input_text”, “label”: “Название” “name”: “title” } metro {

{
“type”: “input_text”,
“label”: “Название”
“name”: “title”
}

metro {
list {
items

{
title
}
}
}
Слайд 49

query { offices { title photoSrc address metro { list

query {
offices {
title
photoSrc
address
metro {
list {

title
}
}
shortDescription
price {
month
}
}
}
Слайд 50

Изменение в процессе добавления/ изменения примитивной сущности BACKEND ДО ПОСЛЕ

Изменение в процессе добавления/ изменения примитивной сущности

BACKEND

ДО

ПОСЛЕ

Разработка Логики хранения данных

Разработка логики

CRUD

Разработка интерфейса управления

Добавление/ расширение запроса

Обновление документации API

Обновление конфигурации

Разработка логики CRUD

Разработка интерфейса управления

Добавление/ расширение запроса

Обновление документации API

Слайд 51

FRONTEND ДО ПОСЛЕ Изучение документации Добавление нового запроса Обработка данных

FRONTEND

ДО

ПОСЛЕ

Изучение документации

Добавление нового запроса

Обработка данных

Изучение документации

Расширение Query

Обработка данных

Изменение в процессе добавления/

изменения примитивной сущности
Слайд 52

ОБНОВЛЕНИЕ ДАННЫХ ЧЕРЕЗ GRAPHQL

ОБНОВЛЕНИЕ ДАННЫХ ЧЕРЕЗ GRAPHQL

Слайд 53

GraphQL. Мутации mutation { office { update (id:123, model: {title: "newTitle"}) } }

GraphQL. Мутации

mutation {
office {
update (id:123, model: {title: "newTitle"})
}
}

Слайд 54

GraphQL. Обновление данных { taskModule { task (id: 123) {

GraphQL. Обновление данных

{
taskModule {
task (id: 123) {
mainInfo (

title: “title”,
description: “description”
)
}
}
}

POST /taskModule/task/mainInfo?id=123
{
title: “title”,
description: “description”
}

Слайд 55

Слайд 56

ОСОБЕННОСТИ GRAPHQL

ОСОБЕННОСТИ GRAPHQL

Слайд 57

Обычный запрос в REST API Запрос Парсинг запроса Определение контроллера Запуск контроллера Получение результата Ответ

Обычный запрос в REST

API

Запрос

Парсинг запроса

Определение контроллера

Запуск контроллера

Получение результата

Ответ

Слайд 58

API … Как работать с GraphQL. Асинхронность Запрос Ответ Парсинг

API


Как работать с GraphQL. Асинхронность

Запрос

Ответ

Парсинг запроса

Определение резолверов

Запуск резолвера

Запуск резолвера

Запуск резолвера

Подготовка ответа

Слайд 59

За чем следить в GraphQL? N+1 Сложность запросов Сложность контроля Кэширование Порог вхождения Асинхронность

За чем следить в GraphQL?

N+1

Сложность запросов

Сложность контроля

Кэширование

Порог вхождения

Асинхронность

Слайд 60

query { task { list { id title } } } Особенности GraphQL. N+1

query {
task {
list {
id
title
}
}
}

Особенности GraphQL.

N+1
Слайд 61

query { task { list { id title subtask {

query {
task {
list {
id
title
subtask {
title

}
}
}
}

Особенности GraphQL. N+1

Слайд 62

Особенности GraphQL. N+1 'resolve' => function ($root) { Loader::add($root->id); return

Особенности GraphQL. N+1

'resolve' => function ($root) {
Loader::add($root->id);
return new Deferred(

function () use ($root) {
Loader::prepareData();
return Loader::get($root->id);
}
);
},
]
Слайд 63

Как работать с GraphQL. Сложность запроса task { subTask {

Как работать с GraphQL. Сложность запроса

task {
subTask {
subTask {

subTask {
subTask {
id
}
}
}
}
}
Слайд 64

1. task { 2. subTask { 3. subTask { 4.

1. task {
2. subTask {
3. subTask {
4. subTask

{
5. subTask {
6. id
}
}
}
}
}

ОГРАНИЧЕНИЕ ГЛУБИНЫ ЗАПРОСА

Query Depth < 4

Слайд 65

3*i5 1. task { subTask { subTask { subTask {

3*i5

1. task {
subTask {
subTask {
subTask {
subTask {

id
}
}
}
}
}

ОГРАНИЧЕНИЕ СЛОЖНОСТИ ЗАПРОСА

Query Complexity < 40

3*i2

3*i3

3*i4

3*i6

Слайд 66

Как работать с GraphQL. Кэширование Кэширование на уровне web-сервера GET /api/info cache КЛИЕНТ Приложение

Как работать с GraphQL. Кэширование

Кэширование на уровне web-сервера

GET /api/info

cache

КЛИЕНТ

Приложение

Слайд 67

Как работать с GraphQL. Кэширование POST /graphql Кешировать на основании

Как работать с GraphQL. Кэширование

POST /graphql

Кешировать на основании body

КЛИЕНТ

Приложение

Кэширование на уровне

web-сервера
Слайд 68

Как работать с GraphQL. Кэширование GET /api/info cache public function

Как работать с GraphQL. Кэширование

GET /api/info

cache

public function actionInfo()
{
$query

= ''; //фиксированный запрос
return GraphQLHandler::handleQuery($query);
}

Клиент

Приложение

Кэширование на уровне web-сервера

Слайд 69

Зачем GraphQL, если и так сойдет? Внедрение GraphQL. Сложность адаптации

Зачем GraphQL, если и так сойдет?

Внедрение GraphQL. Сложность адаптации

Слайд 70

А почему не GraphQL? Внедрение GraphQL. Сложность адаптации

А почему не GraphQL?

Внедрение GraphQL. Сложность адаптации

Слайд 71

API … Как работать с GraphQL. Асинхронность 2 Запрос Ответ

API


Как работать с GraphQL. Асинхронность

2

Запрос

Ответ

Парсинг запроса

Определение резолверов

Запуск резолвера

Запуск резолвера

Запуск резолвера

1

2

N

Подготовка ответа

Слайд 72

Как работать с GraphQL. Асинхронность REST API GET user/info GET account/money GET something/more

Как работать с GraphQL. Асинхронность

REST

API

GET user/info

GET account/money

GET something/more

Слайд 73

Инициализация запроса ~ от 30мс (PHP) Как работать с GraphQL. Асинхронность

Инициализация запроса ~ от 30мс (PHP)

Как работать с GraphQL. Асинхронность

Слайд 74

Как работать с GraphQL. Долгие поля

Как работать с GraphQL. Долгие поля

Слайд 75

Один тяжелый или много легких? Внедрение GraphQL. Постановка вопроса

Один тяжелый или много легких?

Внедрение GraphQL. Постановка вопроса

Слайд 76

ТЕСТОВЫЙ КЕЙС

ТЕСТОВЫЙ КЕЙС

Слайд 77

Нагрузочный тест. Инструментарий

Нагрузочный тест. Инструментарий

Слайд 78

SQLITE Nuxt.JS PHP-SLIM Нагрузочный тест API

SQLITE

Nuxt.JS

PHP-SLIM

Нагрузочный тест

API

Слайд 79

Redis Node.JS PHP-SLIM Нагрузочный тест API

Redis

Node.JS

PHP-SLIM

Нагрузочный тест

API

Слайд 80

Нагрузочный тест. Инструментарий ОЗУ: 1ГБ SSD: 30ГБ CPU: 1 Backend

Нагрузочный тест. Инструментарий

ОЗУ: 1ГБ
SSD: 30ГБ
CPU: 1

Backend

PHP 7.2
Slim Framework
webonyx/graphql-php

Frontend

Node.JS 10.16
Express
Axios HTTP

Client
Слайд 81

Нагрузочный тест. Условия 30 одновременных пользователей Суммарное количество запросов: 200 каждый

Нагрузочный тест. Условия

30 одновременных пользователей
Суммарное количество запросов: 200 каждый

Слайд 82

Кейс 1. Список товаров … Товар 1 Товар 2 Товар

Кейс 1. Список товаров


Товар 1

Товар 2

Товар 3

Товар N

Сравнение получение одинакового количества данных
Проверка

влияния N+1 на результат
Слайд 83

Кейс 1. Список товаров Среднее время ответа (мс)

Кейс 1. Список товаров

Среднее время ответа (мс)

Слайд 84

Кейс 2. Карточка товара без связей Описание товара Фото товара Характеристики товара

Кейс 2. Карточка товара без связей

Описание товара

Фото
товара
Характеристики товара

Слайд 85

Кейс 2. Карточка товара без связей Среднее время ответа (мс)

Кейс 2. Карточка товара без связей

Среднее время ответа (мс)

Слайд 86

Кейс 3. Карточка со связями Фото товара Описание товара Характеристики

Кейс 3. Карточка со связями

Фото
товара

Описание
товара

Характеристики товара

Отзывы о товаре

Связанные товары

Рейтинг

пользователя

Рейтинг товара

Наличие в корзине

Слайд 87

Кейс 3. Карточка со связями Среднее время ответа (мс)

Кейс 3. Карточка со связями

Среднее время ответа (мс)

Слайд 88

Небольшой вывод Стоит ли подключать GraphQL в реальные проекты? Да,

Небольшой вывод

Стоит ли подключать GraphQL в реальные проекты?

Да, но всегда помнить

о:

N+1
Сложностях кеширования
N+1
Сложности запроса
N+1

Слайд 89

Интерфейс Работа с подписками curl export CPU 20% от создателей

Интерфейс
Работа с подписками
curl export
CPU 20%

от создателей GraphQL

интеграция с кодом проекта

Как работать

с GraphQL. Инструменты

JS-GraphQL

GraphiQL

Слайд 90

Как работать с GraphQL. Библиотеки Frontend Backend graphql-go/graphql webonyx/graphql-php graphql/graphql-js vuejs/vue-apollo apollographql/react-apollo

Как работать с GraphQL. Библиотеки

Frontend

Backend

graphql-go/graphql

webonyx/graphql-php

graphql/graphql-js

vuejs/vue-apollo

apollographql/react-apollo

Слайд 91

Когда GraphQL усложняет процессы В некоторых MVP В системах отчетности

Когда GraphQL усложняет процессы

В некоторых MVP

В системах отчетности и аналитики

В общих

сервисах аутентификации

В командах где не знают GraphQL

1

2

3

4

Имя файла: Переход-от-REST-API-к-GraphQL-на-примере-реальных-проектов.pptx
Количество просмотров: 79
Количество скачиваний: 0