У статті наведено набір інструментів, необхідних для створення REST API. Інструменти не залежать від платформи, тобто вони застосовні до API REST, створеного з використанням будь-якого технологічного стека. Мета статті - познайомити розробників API-початківців з різними етапами розробки API і представити інструменти, які допомагають на цих етапах. Детальне освітлення цих інструментів можна знайти в Інтернеті. Етапи розробки API наведені нижче.
- Проектування. Основною метою тут є визначення форми API, інтерфейсів документів та надання кінцевих точок.
- Тестування. На цьому етапі проводиться функціональне тестування API, шляхом надсилання запиту та аналізу відповіді на різних рівнях видимості, а саме: програма, HTTP, мережа.
- Веб-хостинг. При розгортанні в Інтернеті існують інструменти HTTP, які допомагають з розміщенням API-інтерфейсів для підвищення продуктивності, безпеки та надійності.
- Продуктивність. Перш ніж перейти до роботи, ми використовуємо інструменти для тестування продуктивності API-інтерфейсів, що інформують нас про навантаження: яке можуть підтримувати API-інтерфейси.
- Можливість спостереження. Після розгортання API у робочому середовищі тестування у виробничому середовищі забезпечує загальний стан працездатних API та попереджає нас про будь-які проблеми.
- Керування. На закінчення, ми розглянемо деякі інструменти для управління API, такі як формування трафіку, розгортання і т.д.
На наступному малюнку показані різні етапи та використовувані інструменти.
Проілюструємо використання інструментів для API, що надаються веб-програмою, при розробці кожного етапу API. Product Catalog
- це веб-додаток Spring Boot, який керує каталогом товарів. Він надає API REST для виконання операцій CRUD над каталогом продуктів. Код доступний
тут
.
Проектування
На етапі проектування розробник API взаємодіє з клієнтами API та постачальником даних для отримання форми API. REST API насправді складається з обміну повідомленнями JSON по HTTP. JSON є домінуючим форматом REST API, оскільки він компактний, простий для розуміння і має гнучкий формат, який не вимагає попереднього опису схеми. Крім того, різні клієнти можуть використовувати один і той же API і читати потрібні дані.
Розглянемо проект API, використовуючи Swagger. Цей інструмент використовує відкритий формат для опису API у поєднанні з веб-інтерфейсом для візуалізації інформації про інтерфейси. Немає поділу між проектом та реалізацією. Перевага Swagger полягає в тому, що API та документація також будуть синхронізовані, при цьому документація розміщується разом з API. Недоліком є те, що лише розробники API можуть змінювати структуру API. Оскільки документація генерується з API, потрібно спочатку створити каркас нашого API. Використовується Spring Boot для розробки API та пакету Springfox для створення документації.
Додати до вашого pom.xml залежності swagger 2 і swagger-ui maven.
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.5.0</version> </dependency>
Додайте SwaggerConfig.java до проекту з таким змістом:
package com.rks.catalog.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()).build(); } }
Ця конфігурація говорить Swagger сканувати всі контролери і включати всі URL-адреси, визначені в цих контролерах для документації API.
Після запуску програми можна ознайомитися з документацією Swagger API за URL-адресою:
http://localhost:8080/swagger-ui.html
Клацніть на кожен API, щоб вивчити деталі - URL, заголовки HTTP та тіло HTTP. Корисною є кнопка "Try it out!", яка забезпечує пісочницю, дозволяючи користувачам пограти з API, щоб вивчити його роботу, перш ніж почати підключати до своїх додатків.
Тестування
Функціональне тестування API REST тягне за собою відправлення HTTP-запитів та перевірку відповідей, щоб була можливість перевірити, чи працюють API так, як ми очікуємо. REST використовує HTTP як транспорт, що визначає формати запитів та відповідей API. TCP/IP, у свою чергу, приймає HTTP-повідомлення та вирішує, як їх передавати по проводах. Представляємо три набори інструментів для тестування API на трьох рівнях стеку протоколів, а саме: клієнти REST для рівня REST, веб-налагоджувачі для рівня HTTP та аналізатори пакетів для рівня TCP/IP.
- Postman - це REST-клієнт, який дозволяє нам тестувати REST API. Це дозволяє нам:
- Створювати HTTP-запити та генерувати еквівалентні команди cURL, які можна використовувати у скриптах.
- Створювати кілька середовищ для Dev, Test, Pre-Prod, оскільки кожне середовище має різні конфігурації.
- Створювати колекцію тестів, яка має кілька тестів для кожної області продукту. Різні частини тесту можуть бути параметризовані, що дозволяє перемикатися між середовищами.
- Створювати фрагменти коду JavaScript для розширення тестів. Наприклад, для підтвердження кодів повернення або встановлення змінних середовища.
- Автоматизувати запуск тестів за допомогою інструмента командного рядка Newman.
- Імпорт / експорт тестових колекцій та середовищ.
- cURL - це інструмент командного рядка, який використовує свій власний стек HTTP і доступний кроссплатформенно.
curl -X POST \ http://localhost:8080/books \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "id":"1", "author":"shakespeare", "title":"hamlet" }'
-
Burp
- це відладник HTTP, який дозволяє нам бачити веб-трафік, який проходить між клієнтом та API. Він працює як проксі між клієнтом та сервером, що дозволяє нам перехоплювати запит та відповідь та змінювати їх для створення сценаріїв, які інакше складно протестувати без зміни клієнта. Burp - це набір інструментів, який в основному використовується для тестування безпеки, але може бути дуже корисний для тестування API. Налаштуйте свій Postman для надсилання запиту на проксі Burp, а потім налаштуйте Burp для перехоплення запиту клієнта та відповіді сервера.
Перехопіть запит та відповідь, як показано нижче.
- Wireshark - перевірка деяких функцій API, наприклад шифрування, стиснення і т. д., вимагатиме від нас більш глибокого вивчення, щоб побачити, що відправляється та приймається в мережі. Wireshark - це інструмент, який контролює мережевий інтерфейс та зберігає копії всіх TCP-пакетів, що проходять через нього. Трафік ділиться по шарах - HTTP, TCP, IP і т. д. Є помічником усунення проблем, які вимагають більш глибокого вивчення, наприклад, квитування TLS.
Веб хостинг
У цьому розділі ми розглянемо деякі функції протоколу HTTP, які при правильному використанні допомагають надавати високопродуктивні, високодоступні, надійні та безпечні API. Зокрема, розглянемо три частини протоколу HTTP – кешування для продуктивності, DNS для високої доступності та масштабованості та TLS для безпеки транспорту.
- Кешування - один з найкращих способів підвищити продуктивність клієнта та знизити навантаження на API. HTTP дозволяє клієнтам зберігати копію ресурсу локально, надсилаючи у відповідь заголовок кешування, так що наступного разу клієнт відправляє HTTP-запит на той самий ресурс, який обслуговується з локального кешу. Це заощаджує мережевий трафік та обчислювальне навантаження на API.
- Кешування терміну дії HTTP 1.0 надає заголовок Expires у відповіді HTTP, що вказує час, коли ресурс закінчиться. Це може бути корисним для загального ресурсу з фіксованим терміном дії.
- Кешування терміну дії HTTP 1.1 забезпечує більш гнучкий контроль кешування заголовка терміну дії, що інструктує клієнта кешувати ресурс протягом періоду, встановленого у значенні max-age. Існує інше значення s-maxage, яке можна встановити для посередників, наприклад, кеш проксі.
- Кешування перевірки HTTP. При кешуванні існує проблема з клієнтом, що має застарілий ресурс, або двома клієнтами, що мають різні версії одного й того самого ресурсу. Якщо це неприйнятно або існують персоналізовані ресурси, які не можна кешувати, наприклад, токени аутентифікації, HTTP забезпечує кешування перевірки. За допомогою кешування перевірки HTTP надає заголовки у відповідному Etag або останній зміненій тимчасовій мітці. Якщо API повертає один із двох заголовків, клієнти кешують його і включають наступні виклики GET для API.
GET http://api.endpoint.com/books If-none-match: "4v44ffgg1e"
Якщо ресурс не змінено, API поверне відповідь 304 Not Modified без тіла, і клієнт зможе безпечно використати свою кешовану копію.
- DNS - система доменних імен знаходить IP-адреси для доменного імені, щоб клієнти могли надіслати свій запит на правильний сервер. Коли виконується запит HTTP, клієнти спочатку запитують DNS-сервер, щоб знайти адресу хоста, а потім надсилають запит безпосередньо на IP-адресу. DNS - це багаторівнева система, яка кешується, щоб гарантувати, що запити не сповільнюються. Клієнти підтримують кеш DNS, потім є проміжні DNS-сервери, що ведуть до сервера імен. DNS надає CNAME (канонічні імена) для доступу до різних частин сервера, наприклад, API та веб-сервер можуть бути розміщені на одному сервері з двома різними CNAME - api.endpoint.com та www.endpoint.com - або CNAME можуть вказувати на різні сервери. CNAME також дозволяє нам відокремлювати частини нашого API. Для запитів HTTP GET у нас може бути окремий CNAME для статичних та транзакційних ресурсів, що дозволить настроїти зовнішній проксі-сервер для ресурсів, які, як ми знаємо, можуть потрапити до кешу. У нас також може бути CNAME для запитів HTTP POST для поділу операцій читання та запису, щоб ми могли масштабувати їх незалежно. Або ми можемо забезпечити швидку смугу для пріоритетних клієнтів.
При використанні розширеного DNS, такого як Route53, один CNAME замість простої вказівки на один сервер може вказувати на кілька серверів. Політику маршрутизації можна налаштувати для зваженої маршрутизації, маршрутизації із затримкою або для відмови.
- TLS - ми можемо захистити наші API за допомогою TLS, що дозволяє нам обслуговувати наш запит на HTTPS. HTTPS працює за основним принципом безпеки кількох ключів. Щоб увімкнути HTTPS у нашому API, нам потрібен сертифікат на нашому сервері, який містить пару відкритих та закритих ключів. Сервер надсилає відкритий ключ для клієнта, який використовує його для шифрування даних, а сервер використовує свій закритий ключ для його розшифровки. Коли клієнт вперше підключається до кінцевої точки HTTPS, відбувається handshake, тобто клієнт і сервер домовляються про те, як зашифрувати трафік. Відбувається обмін ключем, що є унікальним для сеансу, який використовується для шифрування та дешифрування даних протягом усього сеансу. Під час початкового handshake спостерігається зниження продуктивності через асиметричне шифрування, але як тільки з'єднання встановлено, використовується симетричне шифрування, що відбувається досить швидке.
Щоб проксі-сервери кешували трафік TLS, ми повинні завантажити той самий сертифікат, який використовується для шифрування трафіку. Проксі повинен мати можливість розшифровувати трафік, зберігати його у своєму кеші, шифрувати його тим самим сертифікатом та надсилати клієнту. Деякі проксі-сервери це не дозволяють. У цьому випадку рішення полягає в тому, щоб мати два CNAME - один для статичних кешованих ресурсів по HTTP і другий для персоналізованих ресурсів, що не кешуються, запити яких по захищеному каналу TLS будуть обслуговуватися API безпосередньо.
Продуктивність
У цьому розділі розглянемо інструменти для тестування навантаження нашого API для кількісного визначення обсягу трафіку, з яким може впоратися наша інфраструктура. Основна ідея тестування продуктивності полягає в одночасному відправленні великої кількості запитів в API та визначенні того, в який момент продуктивність падає та дає збій.
Ось питання, на які нам потрібні відповіді:
- Який час відгуку може дати API за різних умов навантаження?
- Скільки одночасних запитів може обробити API без помилок?
- Яка інфраструктура потрібна для досягнення бажаної продуктивності?
loader.io – це безкоштовна хмарна служба тестування навантаження, яка дозволяє нам проводити стрес-тестування наших API. Щоб отримати базову продуктивність API, можна запускати різні види навантажувальних тестів з навантаженнями, що збільшуються, вимірюваними за кількістю запитів в секунду для визначення показників продуктивності, кількісно оцінені з помилок і часу відгуку, для:
- Теста на витримування - середнє навантаження за тривалі періоди, наприклад, на 48 годин при 1 запиті на секунду. Це дозволить виявити будь-які витоку пам'яті або інші подібні приховані помилки.
- Навантажувального тесту - пікове навантаження, наприклад, запуск 2K запитів за секунду з 6 екземплярами API.
- Стресс-теста - пікове навантаження під час навантаження, наприклад, виконання 10 000 запитів на секунду протягом 10 хвилин.
Це також дозволяє визначити інфраструктуру, яка дозволить нам надавати API з потрібними показниками продуктивності та лінійним масштабуванням нашого рішення.
Можливість спостереження
Розгортання API у виробництві не означає, що ми можемо забути про API. Розгортання виробництва запускає ще один етап тестування - тестування у процесі виробництва, яке може виявити проблеми, не виявлені на ранніх етапах. Тестування у виробничому процесі включає набір дій, об'єднаних в єдине ціле: спостережуваність (включають ведення журналу), моніторинг, відстеження. Інструменти для цих дій допоможуть діагностувати та вирішувати проблеми, виявлені на виробництві.
- Ведення журналу має здійснюватися розробниками у явному вигляді з використанням переважного середовища ведення журналу та стандарту ведення журналу. Наприклад, один оператор журналу для кожних 10 або більше рядків коду, якщо код складний з рівнями журналу, розділеними на - 60% DEBUG, 25% INFO 10% WARN та 5% ERROR.
- Моніторинг - виконується більш високому рівні, ніж реєстрація. У той час як реєстрація явно говорить нам про те, що відбувається з API, моніторинг забезпечує загальний стан API, використовуючи загальні метрики, що надаються платформою та самим API. Метрики зазвичай надаються агентом, розгорнутим на сервері, так само вони можуть бути частиною рішення і періодично збираються за допомогою рішення для моніторингу, розгорнутого віддалено.
Рішення можуть бути включені діагностичні кінцеві точки, які повідомляють про загальний стан API.
- Трасування - Zipkin - це розподілена система трасування. Допомагає збирати часові дані, необхідні для усунення проблем із затримками у мікросервісних архітектурах.
Включення централізованого ведення журналу охоплює ведення журналу та трасування. Для моніторингу цікаві метрики можуть бути збережені у сховищі тимчасових рядів, таких як Prometheus, та візуалізовані з використанням Grafana.
Керівництво
Інструменти управління API служать шлюзом, що надає послуги:
- Клієнти API забезпечують себе, отримуючи ключ API;
- Постачальники API настроюють DNS, кешування, політики регулювання, керування версіями API і т.д.
Ці та інші функції доступні на AWS API Gateway.