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
0
200
Что не так с REST
Иван Гришаев
Deep Refactoring
August 31, 2017
Tweet
Share
More Decks by Deep Refactoring
See All by Deep Refactoring
Поворот на 90°
deeprefactoring
0
130
Card Payments 101
deeprefactoring
0
130
Звонки на стероидах
deeprefactoring
0
120
Make Time
deeprefactoring
0
87
Learn-to-Rank или как научить бездушную машину хорошо искать
deeprefactoring
0
180
Уменьшаем количество рефлексии в коде
deeprefactoring
1
91
Прикладная кодогенерация для Java разработчика
deeprefactoring
0
430
Пишем игровой навык для Алисы Яндекс с помощью Excel
deeprefactoring
0
180
Подружиться с исключениями. Иван Гришаев, Exoscale
deeprefactoring
0
190
Other Decks in Education
See All in Education
2025-10-30 社会と情報2025 #05 CC+の代わり
mapconcierge4agu
0
110
Semantic Web and Web 3.0 - Lecture 9 - Web Technologies (1019888BNR)
signer
PRO
2
3.2k
【ベテランCTOからのメッセージ】AIとか組織とかキャリアとか気になることはあるけどさ、個人の技術力から目を背けないでやっていきましょうよ
netmarkjp
2
2.8k
XML and Related Technologies - Lecture 7 - Web Technologies (1019888BNR)
signer
PRO
0
3.2k
TinyGoをWebブラウザで動かすための方法+アルファ_20260201
masakiokuda
2
220
滑空スポーツ講習会2025(実技講習)EMFT学科講習資料/JSA EMFT 2025
jsaseminar
0
230
国際卓越研究大学計画|Science Tokyo(東京科学大学)
sciencetokyo
PRO
0
47k
【dip】「なりたい自分」に近づくための、「自分と向き合う」小さな振り返り
dip_tech
PRO
0
230
1125
cbtlibrary
0
170
JavaScript - Lecture 6 - Web Technologies (1019888BNR)
signer
PRO
0
3.1k
20251119 如果是勇者欣美爾的話, 他會怎麼做? 東海資工
pichuang
0
170
Use Cases and Course Review - Lecture 8 - Human-Computer Interaction (1023841ANR)
signer
PRO
0
1.4k
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.9k
Deep Space Network (abreviated)
tonyrice
0
49
Agile that works and the tools we love
rasmusluckow
331
21k
Typedesign – Prime Four
hannesfritz
42
2.9k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
290
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
67
Done Done
chrislema
186
16k
Designing for Performance
lara
610
70k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.3k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
76
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
Вопросы