Поради та найкращі практики з розробки API REST - Частина 1

Вступ та планування

Це перша в серії з трьох публікацій на API REST.

• Частина 1: Вступ та планування
• Частина 2: Пропозиції щодо схем, поширені помилки та депресія
• Частина 3: Підказки щодо документації та вихід за межі основ

ВСТУП

Ці програми сьогодні є скрізь. Якщо ви розробляєте програми з підтримкою мережі, швидше за все, ви споживали принаймні один код у своєму коді, і цілком можливо, ви читаєте це, оскільки ви збираєтесь написати один із своїх.

Що це серія, а що ні

Ця серія дописів не є вступом до REST. Це передбачає, що ви чітко розумієте, що таке REST і що він має на меті досягти. Це також далеко не всебічна стаття найкращих практик щодо розробки та розробки веб-API. В Інтернеті дуже багато таких, і я б запропонував прочитати стільки, скільки зможете.

Здебільшого це перелік дуже поширених і часто недооцінених помилок, які люди роблять при розробці та впровадженні API REST. Я знаю, не тільки тому, що я стикався з ними в API інших людей, а й тому, що я сам їх створив. :)

Чому це було написано

У ідеальному світі перше, що кожен повинен зробити відразу після розробки API REST, - це написати клієнтську заявку на це. Я вже не говорю про інтерфейс користувача зі списком кінцевих точок, за якими можуть телефонувати люди, а не про фактичне використання вашого API. Немає нічого більш очейного, щоб виявити неефективність вашого творіння, ніж насправді потрібно правильно ним користуватися. Я це знаю, бо мені довелося це робити десятки разів.

Звичайно, наш світ не є ідеальним, і більшу частину часу розробнику доводиться переходити до інших речей після того, як вони закінчать реалізацію API, але лише до тих пір, поки споживачі API не повинні викликати його назад, щоб спокутувати його гріхи. Я також багато разів опинився в цьому нещасному становищі, тому, сподіваємось, мої помилки та поради допоможуть вам заощадити час - так що вам не доведеться повертатися до свого API-API, поки не настав час додавати нові функції.

ПЛАНУВАННЯ

Зображення люб’язно надано Деном Біккеллом

1. Перш ніж почати

Вивчіть стільки документів та розробок документів REST API та книг, як ви знайдете! Я не згадую тут загальних порад, таких як використання іменника замість URIs дієслів (ой, я щойно зробив ...) тощо, але це тому, що я припускаю, що ви вже читали про них в інших місцях.

Розглянемо альтернативи

REST досить популярний як парадигма, але він в багатьох смаках. Перш ніж продовжувати далі, вам слід ознайомитись із якомога більшою їх кількістю. Поки ви не забуваєте перевірити GraphQL - зовсім інший підхід, який не тільки здається чудовим для певних випадків використання, але також використовується Facebook (який його розробив) та новий v4 API GitHub.

Подивіться, що зробили інші

Ознайомтесь і спробуйте використати якомога більше популярних API від авторитетних організацій. Ось декілька для початку: GitHub, Stripe, Twitter, PayPal

2. Фонд

Не припускайте, що ваш API залишиться малим - це майже ніколи не буває. Навіть якщо ви єдиний, хто використовує його для свого власного клієнтського додатка, досить скоро вам знадобиться додаткова кінцева точка, пагинація, аналітика, тестовий режим і хто ще що знає, і це ще до того, як ваш додаток стане популярним та запускаються інші люди запит на доступ до вашого API…

Гаразд - можливо, це розтяжка; але як це зазвичай буває в розробці програмного забезпечення, якщо ви не закладете міцного фундаменту на ранніх етапах, ви заплатите за це дорого в довгостроковій перспективі. Оскільки API повинні бути послідовними, щоб їх було легко споживати, намагання додати до них функції за допомогою клейкої стрічки не ускладнить роботу лише для вас, але і для ваших клієнтів.

Крім того, чим краще ви тримаєте речі в чистоті, тим менше часу потрібно для їх завершення і досить скоро ...

3. Специфікація

Якщо говорити про міцний фундамент; спробуйте створити специфікацію для вашого API, перш ніж почати писати код. Я знаю, що це звучить нудно, якщо ви цього не робили раніше, але це окупається в довгостроковій перспективі і економить багато часу та клопоту.

Специфікація OpenAPI (OAS - раніше Swagger), здається, є найпопулярнішим шляхом на даний момент, оскільки все більше організацій та альтернатив сходяться на ній. Крім того, Postman - це чудове середовище розробки API, але воно безкоштовне лише для приватних осіб або невеликих команд розробників.

Я настійно пропоную не ігнорувати цю пораду, якщо ви не розробляєте невеликий внутрішній API, який будете споживати лише ви.

4. Версія

У цій публікації я не зупинюся на різних підходах до версій, оскільки в мережі є багато спеціалізованих ресурсів. Я лише спробую підкреслити, наскільки важливо вибрати чіткий підхід до версії та дотримуватися його релігійно. Я також представлю підхід, який добре допомагає мені протягом багатьох років.

Чому це важливо?

Сильний підхід до версій забезпечує спокій ваших споживачів (а отже, і ваших кінцевих користувачів), оскільки він не дозволяє змінам API порушити функціональність існуючих клієнтських додатків. Навіть коли самі клієнтські програми розробляються тим самим розробником або тією ж організацією, що і API, існує багато сценаріїв, коли застарілі клієнти все ще можуть бути використані на момент появи оновлення API.

Дуже поширеним явищем цього явища є клієнтські програми для мобільних або настільних ОС, де розробники рідко контролюють цикл оновлення. Незалежно від того, наскільки якісні та автоматизовані ваші клієнтські механізми оновлення, ви майже ніколи не можете бути впевнені, що ваші користувачі працюють із останньою версією клієнтських додатків.

iOS має дуже надійний механізм автоматичного оновлення програм, включених за замовчуванням, але, залежно від уподобань користувача та стану мережі, їх пристрій, можливо, не мав би можливості оновити клієнтську програму наступного разу, коли вона запуститься. Те саме стосується новіших версій Android, тоді як старіші версії ще частіше відстають у оновленнях додатків.

З іншого боку, настільні додатки можуть або не можуть забезпечити механізм автоматичного оновлення, але вони в більшості випадків відключаються, і завжди є випадки (наприклад, для корпоративних середовищ), які не дозволяють негайно оновлюватись. Навіть клієнтські програми браузера можуть (і в більшості випадків повинні) бути від'єднані від їхнього резервного копіювання, і тому вони мають зовсім інший цикл випуску, ніж API.

Донесіть зміни до споживачів

Навіть якщо у вас є ідеальний API з найкращою системою версій, все це нічого не означає, якщо ваші споживачі не усвідомлюють його повний потенціал. Спілкування змін та нових функцій має вирішальне значення для ваших користувачів, щоб мати змогу повністю скористатися ними. Ще важливіше - попереджати своїх користувачів досить рано про аспекти, які збираються застарілими або видаляються, щоб у них було достатньо часу для оновлення, тестування та доставки нових версій своїх клієнтів.

Ведення актуальної документації та випуск детальних журналів змін для кожної версії є надзвичайно важливими та мають стати частиною вашого циклу розробки.

Підхід основної / другорядної версії

Підхід до версій, який я дуже цінував протягом багатьох років, є основною / другорядною схемою версій. Ваш API характеризується основним номером версії, який (якщо ви робите все правильно) оновлюється лише тоді, коли відбуваються неполадки, і незначним номером версії, який оновлюється будь-коли, коли є невеликі додаткові додатки.

Якщо дивитися з іншого кута, кожна основна версія гарантує, що структура ресурсів та схеми API не порушиться протягом тривалості її життєвого циклу, незалежно від того, скільки незначних версій випущено тим часом. Незначні версії сумісні назад.

Як правило, основна версія є частиною базової URL-адреси API (наприклад, https://api.myserver.com/v1/endpoint), а другорядну версію можна вибрати через заголовок запиту. Якщо заголовок запиту не надається, використовується остання незначна версія. Існує багато популярних API, які дотримуються такого підходу, моїм улюбленим є Stripe (який використовує дати випуску для другорядних версій).

Хоча я знову згадаю про цей підхід, коли говоритимуть про оновлення вашого API в наступних розділах, вирішувати вибрати власну офіційну систему версій, яка найкраще відповідає вашим вимогам. Просто пам’ятайте, що як тільки ви це зробите, вам доведеться взяти на себе зобов’язання.

5. Тестування

Це добре, коли ви не на виробництві

Як невід'ємна частина процесу розробки програмного забезпечення в цілому, тестування є важливим для вашого API. Оскільки API зазвичай слугують ланкою між єдиним джерелом правди, який є сервером, та одним або декількома клієнтськими програмами, вони повинні бути надійними за будь-яких обставин і не можуть дозволити собі вступити у виробництво, порушене будь-яким чином. Більше того, оскільки вони, як правило, піддаються впливу Інтернету і тому вразливі до великої кількості ризиків, їх необхідно ретельно перевірити на велику кількість загальних і не дуже поширених сценаріїв.

Тестування вручну, зателефонувавши в кінцеві точки за допомогою таких інструментів, як Swagger, Postman або REST-консоль, може допомогти вам лише під час перших кроків розвитку дитини, коли ви ще протестуєте різні основні функції. Підтримка набору автоматизованих тестів з самого раннього періоду значно покращує якість готової продукції.

Завдяки своїй природі API є ідеальними кандидатами для функціонального тестування. Тестування їх внутрішнього впровадження дуже важливо (як і для будь-якого іншого програмного забезпечення), але, на мій погляд, функціональне тестування API та уподібнення його до чорної скриньки забезпечує набагато більше значення часу, який ви витратите на нього.

Підтримання тестової бази даних, яку можна налаштувати та знищити під час тестування, є важливою частиною процесу. Продовжуйте додавати до нього дані, які сприяли минулим проблемам (спостерігали під час розробки або повідомляли ваші споживачі) та збагачуйте свій тестовий набір тестами регресії, щоб переконатися, що ви позбулися цих помилок раз і назавжди.

Ніколи не вважайте, що ваші перевірки вхідних параметрів завершені, поки ви не перевірите навіть найсмішніші крайові випадки (не забувайте, що ваші клієнтські програми самі по собі можуть бути дуже помилковими). Нарешті, вкладіть час у належну інфраструктуру ведення журналу, щоб зловити ці декілька помилок, що залишилися, спостерігати за поведінкою споживачів та використовувати цю інформацію для створення ще більше сценаріїв тестування.

6. Розгортання

Як ви, можливо, вже помічали (або помітите, як читаєте), ця публікація сильно фокусується на тому, як створити API, який не порушує речі. Звичайно, найстрашніша фаза розбиття речей майже у всіх програмних продуктах - це розгортання.

У більшості випадків, якщо ви правильно виконали тестування та версію версій, шанси зіткнутися з проблемою під час розгортання дуже низькі; однак, ось кілька порад, які можуть бути корисними.

Розв’яжіть все

Ось дуже поширений сценарій:

Ваш API надає дані для кількох клієнтів B2B, розроблених зовнішніми організаціями, обслуговує пару мобільних додатків та веб-додаток, розроблений вашою власною організацією, і є невід'ємною частиною серверного додатку, який також може бути доступний через Інтернет , для цілей адміністрації.

Це може здатися складним, але я його бачив багато разів у минулому в більш простих або складних варіаціях. Ключовим моментом тут є те, що API, хоч і є наріжним каменем організації, часто тісно поєднується щонайменше з одним серверним додатком, який має інші обов'язки.

Це означає, що коли настає час оновити серверну програму, якщо щось зламається, є хороший шанс, що API також зламається. Якщо це станеться, API зведе з собою всіх своїх споживачів, і, зрештою, гнів кінцевих користувачів зійде на компанію.

Незручність ваших користувачів - це останнє, що ви хочете

Ще одним недоліком жорсткої зв'язку в цьому контексті є те, що цикл випуску однієї програми впливає на всі інші. Для цього буде потрібно складне планування та упорядкування розгортань. Крім того, з точки зору бізнесу це не має сенсу (кожен додаток має бути випущений у власний час - не впливаючи на решту).

Якщо ваш API та решта ваших додатків розробляються як незалежні модулі вашої інфраструктури, все це проходить. Хтось може заперечити, що наявність більшої кількості модулів означає більше помилок, але це можна вирішити за допомогою належної версії та тестування. Крім того, навіть якщо нова версія вашого API не працює після розгортання, ваша команда буде першою, хто це дізнається. У цьому випадку, якщо нічого кращого не вдається зробити, ви завжди можете затримати випуски своїх клієнтів на пару днів, поки не будете впевнені, що все працює належним чином.

Один небезпечний випадок, який вам доведеться запобігти жорстким тестуванням, - це коли нова версія вашого серверного додатка порушує існуючу версію вашого API. Знову ж таки, єдиний спосіб уникнути цього - це, звичайно, через суворий процес розробки з належною версією та тестуванням. Трактування всіх частин вашої інфраструктури як окремих модулів заохочує цей підхід ще більше.

7. (Витончена) Депресія

У якийсь момент, коли програма перестає дозрівати, неминуче вам доведеться зневірити свою поточну основну версію API на користь нової. Клієнтські додатки, які ще розробляються, також повинні будуть оновити до нової версії, але це може зайняти час.

Більше того, бувають випадки, коли навіть негайні дії розробників не означають негайних оновлень клієнтських додатків. Хоча оновлені версії веб-додатків можуть бути доступні для кінцевих користувачів, як тільки вони випускаються, більш старі версії програм для мобільних пристроїв та нативних ОС, як правило, залишаються на довгий час. Деякі користувачі не дуже розуміють (або навіть не усвідомлюють) процес оновлення програм на своєму телефоні чи на комп’ютері. Якщо ці додатки раптом почнуть працювати несправно, відповідь користувачів може просто припинити їх використання.

Скасування основної версії API не повинно означати переривання служби. Застаріла версія повинна продовжувати працювати саме так, як і раніше, протягом певного періоду часу (наскільки це можливо), який буде чітко та неодноразово повідомлятися вашим споживачам. В ідеалі, старіші версії API ніколи не повинні припиняти свою роботу, якщо вони не становлять загрозу безпеці або не заподіюють іншим чином шкоду вашому сервісному серверу.

8. Часто ігноруються добрі практики

Для ресурсів можна використовувати форми множини або однини, але не обидва

/ автомобілі - це нормально, як і автомобіль, але ви не можете використовувати обидва. Виберіть одну форму та дотримуйтесь її у всьому API. Якщо ви цього не зробите, ви будете плутати своїх споживачів, а можливо, навіть своїх власних розробників або себе в майбутньому.

Повернути оновлені об'єкти у відповідях PUT та PATCH

Після успішного запиту через дієслова PUT або PATCH, клієнту зазвичай потрібно знати стан оновленого ресурсу. Оскільки цілком можливо, що декілька клієнтів можуть оновлювати його одночасно, це єдиний спосіб інформувати кожного про стан ресурсу в момент оновлення.

Файли cookie та PHPSESSIONID

Цей дуже поширений у програмах, розроблених PHP. API використовує власний спеціальний маркер аутентифікації, але невідомий розробнику, який використовує PHP-сеанс за замовчуванням, всі відповіді також містять жахливий файл cookie PHPSESSIONID! Це спричиняє всілякі помилки з часом, тому що ніхто (включаючи розробника) не повідомляється про файли cookie, тому що ніхто не думає, що вони його розмістили.

Файли cookie, як правило, прямо не заборонені REST. Вони можуть спричинити проблеми при неправильному використанні (наприклад, якщо ви намагаєтеся отримати доступ до окремого домену, який також повинен бути авторизований через ваш механізм API), але вони не заборонені жодними специфікаціями. Однак слід уникати використання декількох форм автентифікації одночасно.

Що стосується обробки сеансів PHP, ви ніколи не повинні покладатися на підхід до файлів cookie за умовчанням для вашого API, якщо ви не хочете, щоб файл cookie PHPSESSIONID діяв як маркер аутентифікації вашого API (що я жодним чином не рекомендую!). Моєю порадою буде запровадити спеціальний механізм обробки сеансів, який реалізує ваш бажаний метод аутентифікації.

Не піддавайте внутрішні помилки чи деталі щодо впровадження

Протягом багатьох років я бачив це незліченно, навіть у популярних API великих компаній. Не круто викривати внутрішні (наприклад, SQL) помилки у ваших відповідях! Знайдіть надійний спосіб записати їх для подальшої довідки, але перекладіть їх на загальну 500 - Внутрішня помилка сервера у ваших відповідях API.

Обов’язковий xkcd - завжди актуальний.

Це одне з перших, що слід зробити на початку розвитку. Безпека повинна стати першочерговою турботою про сервіс, який відкривається в Інтернеті.

Це було першим у серії трьох публікацій на API REST.

Наступний можна прочитати тут:
Частина 2: Пропозиції щодо схем, поширені помилки та застарілість