Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Что не так с REST
Search
Deep Refactoring
August 31, 2017
Education
210
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Что не так с REST
Иван Гришаев
Deep Refactoring
August 31, 2017
More Decks by Deep Refactoring
See All by Deep Refactoring
Поворот на 90°
deeprefactoring
0
140
Card Payments 101
deeprefactoring
0
140
Звонки на стероидах
deeprefactoring
0
130
Make Time
deeprefactoring
0
95
Learn-to-Rank или как научить бездушную машину хорошо искать
deeprefactoring
0
190
Уменьшаем количество рефлексии в коде
deeprefactoring
1
99
Прикладная кодогенерация для Java разработчика
deeprefactoring
0
450
Пишем игровой навык для Алисы Яндекс с помощью Excel
deeprefactoring
0
210
Подружиться с исключениями. Иван Гришаев, Exoscale
deeprefactoring
0
210
Other Decks in Education
See All in Education
2026年度春学期 統計学 第8回(オンデマンド配信回) 演習(1)・問題に対する答案の書き方 (2026. 5. 21)
akiraasano
PRO
0
150
良書紹介08_ 頭のいい子がやっているすごいグラフの読み方
bunnchinn3
0
120
Examen de Selectividad. Geografía junio 2026 (Convocatoria Ordinaria). UCLM
juanmartin2026
1
3.1k
Visionary Initiative: Materials-Positive Society 「モノの進化をポジティブな社会の原動力に」|Science Tokyo(東京科学大学)
sciencetokyo
PRO
0
780
「答えを出す」より「わかる」をつくる
kzkmaeda
1
240
Info Session MSc Computer Science & MSc Applied Informatics
signer
PRO
0
300
Course Review - Lecture 13 - Information Visualisation (4019538FNR)
signer
PRO
1
2.7k
データマネジメント試験対策教材1〜データマネジメント基礎〜
yoshimura_datam
1
510
AIには考えられないことを考えられる人になるために
iqbocchi
1
200
!コスパよくインターンに受かる方法!
ruribou
1
310
[2026前期火5] 論理学(京都大学文学部 前期 第11回)「ハーモニー:三層モデルと保存拡大」
yatabe
0
190
プロポーザルを書く技術とアンチパターン/proposal-writing-and-antipatterns
moriyuya
13
3.6k
Featured
See All Featured
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
660
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
520
A better future with KSS
kneath
240
18k
Paper Plane
katiecoart
PRO
2
52k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
45k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
220
New Earth Scene 8
popppiees
3
2.4k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
220
Visualization
eitanlees
152
17k
Mobile First: as difficult as doing things right
swwweet
225
10k
HDC tutorial
michielstock
2
750
Transcript
Что не так с REST Иван Гришаев, Глубокий рефакторинг
API Машинный интерфейс Автоматизация —> Машина —> Машина -X- Человек
-X- Машина —> Машина
API Выбор оператора Тип банковской карты Справки, документооборот Просто нет
нужной апишки
Минутка истории Первые API XML/SOAP XML/RPC WSDL
Минутка истории Интеграция с 1C Python/Suds JSON inside XML/SOAP https://github.com/igrishaev/1c-json
REST Де-факто в индустрии Все фреймворки по REST Масса утилит
(Swagger, RAML) Сервисы/сайты-API Священная корова
REST Не факт, что было задумано именно так Так уж
вышло Вложено много сил Все ли мы делаем правильно?
Неконкретика Что такое REST? Representational state transfer Method + Resource
+ ID
Неконкретика Как передать версию? /api/v1/users /api/users?version=1 "Version": "1" {"name": "Ivan",
"version": 1} (Как вообще версионировать? И нужно ли?)
Неконкретика CRUD are not enough PUT vs POST vs PATCH
Не отражает бизнес-логику
Роспуск группы DELETE /groups/42 Группа не удаляется Затрагиваются пользователи Пишется
история
Дать пользователю скидку POST /users/42/discount PUT /items/42/users/1 PATCH /promo {"user_id":
42, "discount": 10}
Неконкретика В крупных фирмах спеки Google: Resource Oriented Design У
вас стартап, вам некогда
Данные размазаны по всему запросу GET /api/users/?active=true HTTP/1.1 Version: 1
Authentication: Basic Base64String==
Данные размазаны по всему запросу PUT /api/users/1 HTTP/1.1 Version: 1
Authentication: Basic Base64String== {"name": "Ivan", "age": 31}
Данные размазаны по всему запросу Нет смысла Слишком большой скоуп
Такой Request трудно построить Только для веб-сервера верхнего уровня Чтение по частям
Неконкретика Когда GET, обрабатываю query string Когда другой, тело запроса
Нет одного источника данных
Какая разница? import boto import time s3 = boto.connect_s3() bucket
= s3.create_bucket('boto-demo-%s' % int(time.time())) key = bucket.new_key('mykey') key.set_contents_from_string("Hello World!") print key.get_contents_as_string() key.delete() bucket.delete()
Какая разница? String cleanBucketName = bucketName.replaceAll("/$", ""); String uri =
GCS_URI + cleanBucketName; HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory(credential); GenericUrl url = new GenericUrl(uri); HttpRequest request = requestFactory.buildGetRequest(url); HttpResponse response = request.execute(); String content = response.parseAsString();
Кеш? Не нужно Чаще всего кеширование как раз не нужно
Костыли с random query arg Так и быть, разрешить GET + query string Varnish
Зависимость от классов from django.conf.urls import url, include from django.contrib.auth.models
import User from rest_framework import routers, serializers, viewsets class UserRest(BaseRestClass): def on_get(self, request): ... def on_put(self, request): ... def on_post(self, request): ... Как инициализировать класс? Как инициализировать Request? Как переиспользовать on_put?
Swagger Интерфейс Запрещает ошибки, а нам нужно Не сохраняет сессии
(Postman) Убог Вал зависимостей
Как нужно Главное — данные Data-oriented programming Мыслить в терминах
бизнес-логики Alan Kay and Rich Hickey about "data"
Request vs Data Запрос — это не данные, а состояние
Огромный скоуп (сокет, сессия, ...) Нельзя сохранить Данные — постоянны
SEA — single endpoint API Максимально абстрагироваться от транспорта Действие
и аргументы Все в одном месте
SEA — single endpoint API Действие — что делать На
сервере словарь "действие" ⇒ функция Одна функция-диспатчер
SEA — single endpoint API { "action": "list_users", "active_only": true,
# optional "order_by": "name", # optional "version": 1, "performer_id": 42, "signature": "671345234y6234" }
SEA — single endpoint API Метаданные В словаре не только
функции, но и схемы, права и тд
SEA — single endpoint API actions = { "get_user": {
"handler": api.get_user, "schema_in": schemas.get_user_in, "schema_out": schemas.get_user_out, "role": "admin", "doc": "Some API description", "added": "1.4.2", } }
Одна точка входа /users/ /users/42 /users/42/orders/ /order/ /order/42 /customer/ /customers/42
/customers/42/orders/
Одна точка входа А теперь еще клиент! var apiRoutes =
{ get_user: "/users/:id", list_users: "/users/", user_orders: "/users/:id/orders", ... }
Одна точка входа /api {"action": "create_user", "name": "Ivan", "age": 31}
/api {"action": "update_user", "user_id": 1, "name": "Juah"} /api {"action": "delete_order", "order_id": 42} ... 1 функция на сервере 1 функция на клиенте
Масштабируется Не нужно писать новый класс Не нужно добавлять новый
урл Просто новый ключ в словаре Версионирование по ключам (fallback)
Просто, понятно Данные Словари Функции
API знает все о себе Список всех апишек с доками
Рендер документации как нужно нам Апишка, которая возврашает апишки, схемы, метаданные
API знает все о себе список апишек {"action": "list_api"} документация
к апишке {"action": "get_doc", "target": "list_api"} схемы данных {"action": "get_schemas", "target": "get_doc"}
Сценарии {...}, {...}, {...} в файле, в коде VS GET
/users/42 HTTP/1.1 POST /users/ HTTP/1.1 {...} PUT /users/42 HTTP/1.1 {...}
Примеры Вконтакте https://api.vk.com/method/users.get?user_id=210700286&v=5.52 https://api.vk.com/method/pages.getTitles?v=5.51 https://api.vk.com/method/wall.deleteComment?comment_id=123123&v=5.51
Примеры Наш стартап {"action": "users/get", "user_id": 42} {"action": "users/update", "user_id":
42, "name": "Juan"}
Примеры actions = { "get_user": api_get_user, "update_user": api_update_user, "list_users": api_list_users
} def api_update_user(data): user_id = data.pop("user_id") Users.objects.update(data).filter(id=user_id) return response_ok()
Примеры (def action-rules {:displayfixtures/get-nearby {:handler #'nearby-displayfixtures :schema-in s/CQRSNearbyDisplayfixturesIn :schema-out s/CQRSNearbyDisplayfixturesOut}
:displayfixtures/get-all-displayfixtures {:handler #'get-all-displayfixtures :schema-in s/CQRSParams :schema-out s/CQRSGetAllDisplayfixturesOut}
Примеры (defmulti api :action) (defmethod api :users/get [{user_id :id}] ...)
(defmethod api :users/update [params] ...) (defmethod api :default [params] {:status 404})
Преткнования Это не REST!!! У нас так не принято Утилиты
Жалко потраченных сил
Что это дает Независимость от транспорта Очереди, таски, Async Сценарии,
обстрелы Масштабируемость Прозрачность Критичный взгляд
Ссылки From REST to CQRS https://www.youtube.com/watch?v=qDNPQo9UmJA https://martinfowler.com/bliki/CQRS.html https://news.ycombinator.com/item?id=11945722
Вопросы