Як порозумітися бекендеру і фронтендеру, обираючи архітектуру

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

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

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

Тут маємо дві опції: або все переписати і просити людей працювати в понаднормовому режимі, щоб «гасити пожежі», або ж мати вичерпну документацію — пояснення, чому все працює таким чином, — і зберегти логіку проєкту та час розробників.

Ілюстрація Аліни Самолюк

Програмування за контрактом

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

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

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

Архітектура як основа комунікації

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

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

Далі згадаємо кілька архітектурних патернів і підходів до організації взаємодії фронтенду та бекенду.

JSON-RPC

Remote Procedure Call (RPC) — один з найпростіших, проте від того не менш потужних інструментів для розробки клієнт-серверних застосунків. За основу JSON-RPC архітектури взятий найбільш природний спосіб комунікації — виклик функцій інтерфейсу за допомогою HTTP-протоколу.

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

Також він вартий уваги, якщо потрібна розробка дизайну мікросервісної архітектури. Remote Procedure Call (RPC) для мікросервісів з правильною гранулярністю, які реалізують не лише CRUD-операції над об’єктами RPC, може вирішити питання словника і більш складних операцій, що виходять за стандартний набір.

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

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

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

Застосування. Мікросервіси та немасштабні проєкти з невеликим словником об’єктів та детермінованою кількістю дій над ними.

➕ Найменша складність реалізації.

➖ Складність еволюції у разі зростання проєкту.

REST

Найбільш «упевненим» на сьогодні патерном є Representational State Transfer (REST). Він застосовується у більшості вебзастосунків і має низку переваг над RPC.

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

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

Застосування. Моделювання та розробка застосунків із використанням об’єктів і CRUD-операціями над ними.

➕ Найбільш вживана архітектура на сьогодні. Побудована на основі можливостей НТТР-протоколу. Чітка і знайома семантика з іменниками та дієсловами.

➖ Не має нативного вирішення питання надлишкових чи недостатніх даних. Складність реалізації завдань, які не вкладаються в об’єктну модель.

GraphQL

Graph Query Language (GraphQL) — наймолодший патерн зі згаданих, який стрімко набуває популярності серед розробників. Ідея підходу з мовою запитів для Web API не є новою, прикладом такої є SQL-подібний інтерфейс Facebook (FQL).

GraphQL вже своєю назвою наштовхує на думку, що для обґрунтованого вибору цієї архітектури об’єкти, представлені в системі, повинні вкладатися у поняття «графа». Такий підхід є гарним рішенням для створення застосунків для соціальних мереж, які охоплюють велику кількість об’єктів зі щільною залежністю між ними.

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

Звучить привабливо, але GraphQL теж має проблеми, властиві архітектурі резолверів. Один з яскравих прикладів — це N+1 проблема, тобто неефективний підхід до роботи з базою даних, внаслідок якого виникає надмірна кількість запитів до одного і того ж об’єкта. Звісно, кожна проблема має вирішення, але треба бути готовим до таких ситуацій заздалегідь.

Застосування. Проєкти середнього і великого розміру з чіткою об’єктною моделлю та залежностями між об’єктами.

➕ Самодокументована схема даних, вбудована валідація. Можливість роботи з підписками. Конструювання запитів під потреби клієнта.

➖ Молода архітектура та ком’юніті навколо неї. Необхідність розв’язувати проблеми, властиві архітектурі резолверів. Складніша в розумінні за REST та RPC.

Документація як спосіб комунікації

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

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

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

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

Отже, документація може у простий спосіб розв’язати питання передачі інформації новим розробникам і уникнути bus factor проєкту, який виникає при накопиченні знань в однієї людини. Які самі інструменти для документації я застосовував та їхнє порівняння, наводжу далі у статті.

Wiki, або Можливість для самостійних змін даних

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

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

➕ Для використання plain text підходу буде достатньо домовитись про нотацію і формат даних. Є можливість використовувати будь-який текстовий редактор або систему бази знань.

➖ Постійно треба оновлювати документацію власноруч.

Postman

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

Функціонал Postman, безумовно, є ширшим, ніж у plain text, але він також не розв’язує питання зі своєчасним оновленням документації та колекцій, тобто залишається ризик неактуалізованої версії документації.

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

➕ Можливість автоматизованого тестування API, підтримка генерації документації.

➖ Необхідність підтримувати документацію та колекції в актуальному стані власноруч.

Swagger

Специфікація та інструмент для автоматизації документування, який має майже необмежену кількість можливостей для використання, генерації коду, перегляду документації, версіонування.

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

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

Є і деякі практичні переваги в OpenAPI, зокрема можливість використання їх у Postman, але все-таки, обравши цей шлях, ви будете обмежені у можливості вийти за межі специфікації.

➕ Документація змінюється разом з кодом, який сприяє її оновленню.

➖ Велика кількість дубльованої інформації в коді. Необхідність підтримувати актуальність документації власноруч.

GraphQL

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

Деякі проєкти роблять вибір на користь GraphQL саме тому, що код проєкту і є документацією, але треба зважати на те, що ця документація більш технічна. Тобто, якщо нагальна потреба у документації полягає лише у комунікації між розробниками, це «золоте руно», але якщо є необхідність у передачі цієї документації кінцевим користувачам або клієнту — все-таки ви не уникнете написання умовного Wiki.

➕ Код і є документацією. Автоматична перевірка коректності запиту.

➖ Прив’язка до обраної архітектури.

Висновки

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

Попри те, що вибір архітектурних складових проєкту без контексту є вибором заради вибору, як на мене, під час вирішення, яким шляхом піти, «найменшим злом» буде відштовхуватись від REST API. Якщо під час формалізації вимог зрозумієте, що у вас невелика аплікація, завжди зможете розглянути застосування RPC-like підходу. І навпаки: якщо щільність зв’язків між об’єктами у системі велика і розробка запитів під усі можливі кейси фронтенду може внести багато хаосу, час подивитися у бік GraphQL.

З документуванням проєкту трохи інакше, тому що до сьогодні Wiki-системи та їхні аналоги займають почесне місце. І справді, якщо придивитись до більшості проєктів чи то комерційних, чи то open source — їхня документація має довільний формат, у якому можна якнайкраще донести думку. Звісно, якщо ви не маєте потреби в публічній документації для розробки, таких інструментів, як Swagger у випадку REST або RPC чи GraphQL зі своїми схемами, буде більш ніж достатньо.


Щоби не пропустити нові статті Дениса Гасаненка — підписуйтеся на нього у телеграм-боті Стрічки DOU.

Похожие статьи:
Національний банк України 20 травня дозволив фінансовим установам продавати валюту через каси банків та конвертувати кошти...
Привет. В этой статье хочу рассказать о приеме, который поможет вам быстрее исправлять ошибки в Production. Для работы нам...
В рубрике DOU Проектор все желающие могут презентовать свой продукт (как стартап, так и ламповый pet-проект). Если вам...
Об авторе: Денис Морозов, к.ф.-м.н., работает на должности доцента кафедры математики НаУКМА, также является...
З 28 серпня по 4 вересня у Сеґеді (Угорщина) відбулася Міжнародна олімпіада з інформатики. За перемогу...
Яндекс.Метрика