itmozg, Даниил Павлючков
DESCRIPTION
Презентация с технической секции #BitByte - фестиваля профессионального развития, который прошел 19 мая в Санкт-Петербурге. Даниил Павлючков, Team Lead компании ITMozg: «REST: от GET до HMAC или как создать качественное REST API».TRANSCRIPT
![Page 1: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/1.jpg)
1
REST: от GET до HMAC или как создать
качественное REST API
Даниил Павлючков2012г.
![Page 2: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/2.jpg)
2 Наши программы
![Page 3: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/3.jpg)
3 Как им общаться между собой?
???
![Page 4: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/4.jpg)
4 API – это …
API - application programming interface
Интерфейс для коммуникации между ПО.
API состоит из набора классов, процедур, функций, структур, абстрактного от внутренней логики приложения.
![Page 5: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/5.jpg)
Почему API – это хорошо5
• Все сторонние приложения будут работать одинаково хорошо
• Пишется программистом для программиста
• Не нужно выставлять наружу бизнес-логику приложения
![Page 6: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/6.jpg)
Примеры API6
• DirectX• OpenGL• Windows API• Linux Kernel API• Facebook API• Gtk, qt, X11…
![Page 7: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/7.jpg)
“Как я объяснил REST своей жене”
7
http://tomayko.com/writings/rest-to-my-wife
![Page 8: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/8.jpg)
REST (Representational State Transfer) – это подход к созданию архитектуры сетевых протоколов. Этот подход был описан в 2000г Ройем Филдингом, в своей докторской диссертации.
Что же такое REST?8
![Page 9: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/9.jpg)
Рой Филдинг – идейный авторпротокола HTTP и соавтор веб-сервера Apache.
Рой Филдинг9
![Page 10: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/10.jpg)
• Легкая масштабируемость• Общность интерфейсов• Независимое развертывание компонентов• Возможность внедрения посредников
Цели REST10
![Page 11: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/11.jpg)
• Клиент-серверная архитектура• Stateless• Кешируемость• Многослойность• Общий интерфейс
Правила REST11
![Page 12: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/12.jpg)
• Клиенты не задумываются о схеме БД• Серверы не задумываются о UI• Клиенты и серверы могут разрабатываться независимо
Клиент-сервернаяархитектура
12
![Page 13: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/13.jpg)
• Информация о клиенте не хранится на сервере• Каждый запрос клиента содержит всю необходимую информацию для обработки на сервере
Stateless13
![Page 14: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/14.jpg)
Запросы должны явно объявлять себя как кешируемые или нет. Клиент самостоятельно решает, кешировать такой запрос или нет.
Кешируемость14
![Page 15: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/15.jpg)
• Возможно использование посредников, серверов-балансировщиков и кеш-хранилищей
• Клиент не должен знать, подсоединен он сейчас напрямую к серверу или работает с посредником
Многослойность15
![Page 16: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/16.jpg)
Идентичный интерфейс между всеми серверами и всеми клиентами позволяет добиться слабого связывания и хорошего масштабирования.
Общий интерфейс16
![Page 17: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/17.jpg)
Клиент может управлять состоянием ресурсов, через стандартные интерфейсы, при помощи глаголов.
Главный принцип REST17
![Page 18: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/18.jpg)
Ресурс – уникальный объект, доступный по уникальному URL
Глагол – http метод (GET, POST, PUT, DELETE …)
REST over HTTP18
![Page 19: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/19.jpg)
Пример RESTful API19
http://api.com/books http://api.com/books/id17
GET Вывести список URL всех книг Вывести информацию о конкретной книге
POST Добавить одну новую книгу Добавить новый ресурс в конкретную книгу
PUT Заменить все книги новыми Заменить конкретную книгу новой книгой
DELETE Удалить все книги Удалить конкретную книгу
![Page 20: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/20.jpg)
Хорошее API – какое оно?20
???
![Page 21: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/21.jpg)
Что отличает первоклассное API от хорошего API
21
• API легко использовать• API сложно сломать
• Внимание к деталям• Любовь к клиентам
![Page 22: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/22.jpg)
Ключевые моменты22
Их слишком много, давайте по порядку.
![Page 23: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/23.jpg)
Не отвечайте в HTML!23
Всегда отдавайте ответы на машинном языке,XML, JSON, CSV …
![Page 24: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/24.jpg)
Используйте HTTP коды ошибок
24
Если что-то пошло не так, код ошибки долженобъяснять, какая именно часть запроса неработает.
Код ошибки должен быть дополнен уникальным текстовым описанием ошибки.
![Page 25: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/25.jpg)
Различайте 4хх и 5хх ошибки
25
4хх – группа ошибок со стороны клиента. Это значит, что клиент может самостоятельно их исправить без вашей помощи.
5хх – группа ошибок со стороны сервера. Это значит, что клиент может открыть support-ticket, и спустя какое-то время его запрос будет обработан корректно.
![Page 26: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/26.jpg)
Документируйте свое API26
Несколько часов, потраченные на написание документации, сэкономят вам дни ответов на вопросы клиентов.
![Page 27: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/27.jpg)
Поддерживайте и XML, и JSON
27
Помните, что различные языки программирования и различные платформы предпочитают разные форматы данных.
Написать алгоритм конвертации array -> json и array -> xml на сервере займет всего 1-2 дня даже у junior developer.
![Page 28: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/28.jpg)
Будьте аккуратны с oAuth28
Используйте oAuth только, если вы работаете с аналогом реального пользователя в вашем API.
![Page 29: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/29.jpg)
Не заставляйте пользователей генерировать ссылки на запросы
29
Если вас спрашивают GET “product list”, то верните следующую структуру
<products><product id=“1”>http://api.com/products/id1</product><product id=“2”>http://api.com/products/id2</product>
</products>
![Page 30: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/30.jpg)
Запросы должны возвращать ограниченное кол-во данных
30
Если вы спрашиваете GET “product list”, то сервер должен вернуть первые n продуктов.
Сервер также должен вернуть готовые ссылки для next page и prev page
![Page 31: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/31.jpg)
Поддерживайте старые версии своего API
31
Если вы сделали крупное изменение в своем API, выложите его под новой ссылкой • http://api.com/v1/products• http://api.com/v2/products
![Page 32: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/32.jpg)
REST API + security = ??32
![Page 33: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/33.jpg)
Как можно защитить запрос
33
• HTTPS• Basic авторизация• oAuth• Подписать меткой
![Page 34: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/34.jpg)
Алгоритм подписи запросов
34
Для подписи запроса необходима пара user + secret.
Подпись отправляется вместе с запросом, и позволяет проверить как авторство запроса, так и целостность данных.
![Page 35: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/35.jpg)
Что подписывать?35
• Глагол• Ресурс• Дополнительные параметры
![Page 36: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/36.jpg)
Как подписывать?36
Запрос нужно подписывать алгоритмом, который поддерживает подпись на основе секретного ключа.
Для этого идеально подходитHMAC – hash-based message authentication code.
![Page 37: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/37.jpg)
Алгоритм HMAC37
![Page 38: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/38.jpg)
Подписываю!38
Запросhttp://api.com/photos/id547
ЗаголовкиGET /photos/id547 HTTP/1.1Host: api.comDate: Thu, 16 May 2012 19:37:58 +0000
![Page 39: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/39.jpg)
Алгоритм создания подписи
39
1. Начинаем с пустой строки2. Добавляем глагол запроса (GET, POST, PUT, DELETE)3. Добавляем перенос строки \n4. Добавляем точку входа (например, photos/id547)5. Добавляем перенос строки \n6. Добавляем канонизированную строку с параметрами запроса
1. Сортируем все параметры по ключу в натуральном порядке2. urlencode ключ и значение параметра3. Добавляем параметры в одну строку в формате
key1=value1&key2=value2&key3=value3...7. Полученную строку кодируем при помощи hmac с секретом
юзера.8. Кодируем цифровую подпись при помощи base64
![Page 40: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/40.jpg)
Формируем запрос40
Запрос http://api.com/photos/id547
Реальный запрос http://api.com/photos/id547?api_user=john
![Page 41: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/41.jpg)
Подписываем запрос41
http://api.com/photos/id547?api_user=john
Строка для подписи GET\nphotos/id547\napi_user=john
Подпись - xXjDGYUmKxnwqr5KXNPGldn5LbA=
![Page 42: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/42.jpg)
Отправляем запрос42
http://api.com/photos/id547?api_user=john
Подпись xXjDGYUmKxnwqr5KXNPGldn5LbA=
Финальный запросhttp://api.com/photos/id547?api_user=john&signature= xXjDGYUmKxnwqr5KXNPGldn5LbA=
![Page 43: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/43.jpg)
Что делает сервер?43
• Находит secret в БД по имени пользователя • Создает собственный версию подписи• Сравнивает пришедшую подпись с только что созданной
![Page 44: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/44.jpg)
Что еще можно добавить в подпись?
44
• Тип данных• md5 чексумма данных• Время отправки запросов• Дополнительные HTTP заголовки
![Page 45: ITmozg, Даниил Павлючков](https://reader036.vdocuments.pub/reader036/viewer/2022062405/557ef6d8d8b42af44a8b4645/html5/thumbnails/45.jpg)
В заключение45
API – точно такая же часть вашего приложения, как и хранение данных или его бизнес-логика.
Проектируйте API по тем же самым процессам (TDD, MVC …), что и остальные части вашего ПО.