Спарэнне шасцях стыляў API: REST, GraphQL, WebSockets, Webhooks, gRPC, SOAP
Дазвольце дазнаць, як REST, GraphQL, WebSockets, webhooks, gRPC і SOAP рашыюць разныя проблемы абмену данымі, а таксама пазнакоміцца з картою выбору для выбору наяўнага рашэння.
Большасць людзей выбірае REST як свой першы стыль API і потым спрыяе да таго, каб ён вважалі універсальным рашэнням. Аднак так не ўсё. REST — толькі адна з шасця вароў, а пяць іншых існуюць самэлькі таму, што REST сталкаецца з рэальнымі працоўкамі ў певных ситуацыях — рэальныя апдэйты, швядкіе внутраніе вызовы межа службамі, строгіяя ваказанні ў сфэре безпекі падпрыемства і гнучкія форматы даных. Кожны з іншых стылей API у гэтым списку быў створаны, каб рашаць проблемы, з якімі сталкаецца REST.
Якщо REST вам вже знайомы, то тое, што будзе після, чыста адзначыць, калі і чаму вам трэба змяніць інструменты.
Што такое API (адзін параграф, а потым перайдзем да наступнага)
У сваім сутнасці API выступае як промежуточны элемент між двумя системамі і дазваляе ўмоўлівацца межы ямі. Калі вы вводзіце „біряні“ у дапытку на доставку ўжынкі, рэзультаты ўжо не знаходзяцца на вашам тэлефоне. Ваша дапытка надсілае запит на сервер компаніі, а сервер адпавядае дадзеннямі, якія паспаўнаюць з запитам. Правілы, якія керуюць гэтым абменам — як формуецца запит, як выглядае адпаведзь — гэта і є API. Уявіце парабака ў рэстаране: вы ніколі не ходзіце на кухню, ўжо самі брачыце ўжынку; вы проста кажаце парабаку, чаго хочаце, а ён займаецца рэштой. Гэты парабак, по суты, і є API.
Як выявілася, існуе шысць разных варыянтав „парабака“, з якімі вам доведзецца стыкнуцца.
REST: Стандарт і яго меры
REST, як скраценна назва Representational State Transfer, працюе на базе HTTP і спыяецца на два ключовыя прынцыпы: URL, які ідентыфікуе ресурс, які вы хачаце, і метод HTTP, який апісвае дзеянне, якое вы хачаце адрабатаваць над ім.
Чатыры методы пакрываюць практычна все: GET атрымлівае даны, POST стварае новы запис, PUT апдэюе або заменяе існуючы, а DELETE выкасывае яго. Ключовая характэрыстыка REST — абсэнція стану: сервер не зберагае нічога пра паказаныя раней взаімадзеі з вамі. Усё неабходнае для адрабаткі павінна быць уключана ў самы запит, кожны раз.
GET https://api.zomato.com/v1/restaurants?search=biryani
Authorization: Bearer <token>
Калі запит прыбывае, сервер пераканальваецца, хто вы, запоўнівае неабходныя записы з базы дадзенаў і адправляе назад пакет даных у формате JSON.
Дзе ён падходзіць: API, адкрытыя для звароту з корантамі, стандартныя прыкладнасці для стварэння, чытання, апдэйта і выдалення дадзейнаў, а таксама ў всіх сцэнарыях, дзе кліент і сервер чыста аддзелены і патрабуецца прыведамы, добра задокументаваны контракт. REST здобыў свой статус стандарту не без прычыны — ён просты, не выклікае патрэбы у сервера фіксаваць стан сесіі, шырока разумеўся і базуецца на звычайным HTTP.
Дзе ён не падходзіць: у всіх ситуацыях, якія выкалікаюць потрэбу у рэальных апдэйтах (прыкладнасці для чату, тракінг месца знаходжэння ў рэальны час), калі адна экранавая оболонка патрабуець дадзеныя з калькольвіх розных рысаў адразу, або пад час внутранняй камунікацыі служб, дзе чыстая скорасць мае перавагу над чытаемасцю для людзя.
GraphQL: Запытайце толькі тое, што вам патрэбна
У REST існуе вядомая проблема — занадто большое выкарыстоўванне данных. Якщо вызваць канец паадрасу /user, можна атрымаць імя, фота прафіля, возраст, аддзел, зарплату і ўсё большае колькасць іншых полей — хоця на самай працэ ўсё, што трэба было, — это імя та фота. Іншыя проблема — недастатак данных, калі для адзінаго пераказу трэба даны з кальколькох рысурсоў, што вымагае адправкі кальколькох запытанняў REST і з’едынэння рэзультаатаў на стороне кліента.
GraphQL рашае обе проблемы адразу: ўсё за дапамогою адзінага канца паадрасу, які ўжо супакоўваецца з языкам запытання, який дазволяе кліенту точна задаць, кальколькі палей ён хоча атрымаць.
# Instead of hitting /employees/123 and getting everything,
# you describe precisely what you need in the request body
query {
employee(id: "123") {
name
photo
}
}
У адпаведзі є толькі тыя два запрошаныя поля — нічога дадатковага. Трэба і зарплату? Проста дадайце яе ў запыт. Няма прычыны ствараць дзеіншы канец паадрасу для цяго.
GraphQL падтрымае тры відэныя операцыі. Запит чытае данні, выпольваючы тую ж ролю, што і REST GET. Мутацыя запісвае або зменяе данні, заменяючы сабой POST, PUT і DELETE разам. Падпіска ачынае працюючы канал дадзейнаў для пастойных апдэйтаў, функцыонуючы па прынцыпу WebSockets.
Дзе ён падходзіць: фронтэнды з множыцай функцый, якім патрэбны гнучкія форматы дадзейнаў, мобільныя прыкладнення, дзе важліва мінімізацыя розмеру пакета дадзейнаў, а таксама ў будзь-якіх ситуацыях, калі калькі лічэбнікаў — веб, мобільныя прыстроі, інтэграціі з трэцімі сторонамі — падключаюцца да таго ж бэкенду, але кожны з іх патрэбуе разны часткі дадзейнаў.
Якія ў яго недакладнасці: базавыя CRUD-сэрвісы, дзе простыя канцэнтры REST уже чынна добра выконваюць сваю ролю. GraphQL прыносіць справжню складнасць на станове сервера, кэшаванне становіцца значна сложнейшым, чым у REST, і часта ёсць непатрэбным надтлакам, калі вашы патрабаванні да дадзэйнаў стабільныя і чытка апісаныя.
WebSockets: Пастаячая з’ёднанне
Функцыі рэальнага часу адкрываюць фундаментальную слабасць REST. Чыба выявіць, чы не прыйшла новая паведамленне ў чат, кліент на базе REST быў змушаны продавальна пытаться: «Є ўсё новае?» — знову і знову. Якшто падыміць гэта на мільйон адночасовых выкарыстоўвальнікаў, то будзе мільйон запытак за секунду, пры чым пераважная большасць адпавідае «нет», што ёсць чыстаю марнацэйкай.
WebSockets абсалютна пазьрэюць гэтую проблему, заменяючы модель запит-адказ на стойкую, двухнаправленную з’яўлення. Спачатку ёна выглядае як звычны HTTP-запит, але ён несе спецыяльны заголовак для апгрэйда:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Калі сервер яго прыме, гэта HTTP-з’яўлення ператвараецца на з’яўлення WebSocket. З таго моменту кожна з сторон можа надсылаць паведамлення іншай у будзь-які момент, без патрэбы спачатку прасіць разрешэння. Канал застаецца ачытым пакуль адна з сторон не закрое яго намерова.
З’єднання WebSocket працюе чатыра розныя стадіі: Connecting (ведаецца процес узгоджэння), Open (перадача паведамленняў ведзецца у обох напрамках), Closing (пачалася процедура закрыцця) і Closed (з’єднання больш не існуе). Прабаць адправіць даныя праз вже закрытае з’єднанне спрабуе зламаць сервер — гэта частая памылка прыступальнікаў.
Дзе гэта выкорыстоўваецца: жывыя чаты, мнагаадресныя ігры, інструменты рэальнага часу для саўместной рэдагавання, такія як спільныя дакументы, рэальныя рэшты спорта і паведамленні типу push — фактычна ў будзь-якім случае, калі сервер павінен адправіць даныя без просьбы.
Якія ў іх слабасці: звычны выкарыстоўванне для запрашэння дадзеных, калі кліент патрэбуе інфармацыю толькі тады, калі яе працягвае. Адтакуе, што WebSockets падтрымваюць стацыонарныя з’ѐеднання, спрачоўваюць ресурсы сервера. Їх выкарыстоўванне там, дзе паслужыць звычны REST, проста марнавае ўстаткування без жадных выгод.
Webhooks: Сервер вызывае вас
Як REST, так і WebSockets пачынаюцца з кліента: кліент ачыняе з’ѐеднанне, надае запит, а сервер адпавядае. Webhooks цэлкам перакручваюць гэты ляміт — уместо таго, каб вы працягвалі сервера пра змены, сервер самы падключаецца да вас, калі выйшла ўваговая інфармацыя.
Механізм просты. Вы рэгіструеце URL у якой-небудзь сторонней службы і паведамляеце яе, што робіць з тым URL: напрыклад, «коли платеж будзе завершаны, апрацаваць запит типу POST сюды». Як толькі платеж фактычна будзе апрацаваны, прадаўца платежа — Razorpay, Stripe або які бы то ні было іншы — автаматычна апрацоўвае запит да вашага канца-тэрміналу. Не трэба ніякіх цыклаў абслюжвання, ніякога стацыонарнага з’ўязку. Вы проста сядзіце і чакаеце, пакуль прыйдзе вызов.
# What you give Razorpay in setup:
Webhook URL: https://yourapp.com/webhooks/payment
# What Razorpay sends when payment completes:
POST https://yourapp.com/webhooks/payment
{
"event": "payment.captured",
"payload": { "amount": 50000, "order_id": "order_abc" },
"signature": "sha256_hash_here"
}
Парадыграма падтверджэння ня ўзначальна тут — гэта весь захоць. Канецчык вашага webhook є доступны для загальнай публікацыі, што значыць, ў тэорыяй будзе можлівасць кожнам надаць фальшывыя даныя падзеі „payment.captured“ і абмануць вашую систему, каб тая затвердзіла замовленне, якое на самай працэ не было оплачана. Падпис, які ўключаецца ў пакет даных, — это крыптаграфічны хеш, який падтверджае, што запит справядліва прыйшоў ад прадавца. Ваш сервер должен пераканацца ў правамільнасці гэтага падпису пры перадпрацоўкі будзь-чаго з тэла запиту.
Калі яго вжываць: падтверджэнняе оплатаў, змены статусу замовленняў, процесы CI/CD (GitHub павядомляе ваш сервер кожны раз, калі прыбывае новы код), а таксама ў будзь-якім процесе, дзе трэба реагаваць на падзею, якая адбылася ў сторонней системе.
Калі не трэба яго выкарыстоўваць: калі патрэбна мглевая адпаведь у рамках той самай взаімадзеі з корыстнікам. Webhooks працуюць пасля таго, як адбулася дзеянне — яны за сваёю сутнасцю асінхронныя. Калі корыстнік зараз сядзіць пры экране і чакае падтверджэння, REST застаецца кращым выборам.
gRPC: Бінарная шыроць частоты для внутраніх служб
Значныя прыкладнікі рэдка калі ўтвараюцца з аднаго сервера. Напрыклад, платформа Zomato запускае окремыя службы для замовленняў, платежаў, прыемлів паведамленняў і дадзэнняў пра рестараны, і гэтыя службы вызываюць адна другую тысячы разоў на секунду. Якщо весь гэты внутраній абмён ведаць будзе праходзіць через REST, неабходна будзе постоянна серыялізаваць і дэсерыялізаваць JSON. Чытаемасць JSON чудова для разработчыка, які адгледвае логі, але гэтая ж чытаемасць супакоўваеся рэальнымі затратамі на парсаванне, калі обсяг дадзэнняў стае вялікім.
gRPC, якій спачатку дапамога Google для обработкі своего внутршняго трафіку, заменяе JSON на Protocol Buffers (Protobuf) — бінарны формат, які ў дзесяткі разоў болей компактны і быстрэй для кодавання і декодавання. Той самы пакет дадзеных, які REST адправляе у вигляды чытальнага тексту, gRPC адправляе у вигляды ўжоўкнутага бінарнага блока, які машыны обрабоцвалі заўсёды быстрэй.
// You define your data structure once in a .proto file
message OrderRequest {
string order_id = 1;
string user_id = 2;
float amount = 3;
}
Парадоксальна павышэння каркасоў не выключваецца толькі з форматам дадзенаў. gRPC таксама працуе на адной з баз HTTP/2, што дазволяе мультіплексаванне — тыячы запитоў можаць адправляцца через адну спяльную з’ёедынанне адночасна, на вядмэннае HTTP/1.1, який обрабоўвае іх по аднаму. Да гэтага ў gRPC є чатыры разныя моделі кантакту: Unary (адзін запит паўязаны з адной адпаведзю, такі ж формат, як у REST), Server Streaming (адзін запит, які ініціеюе стрым адпаведзяў, падходзячы для такога, як жывой статус замовлення), Client Streaming (многа запитоў, якіе злучаюцца ў адну заканчоўную адпаведзь, корыстныя для заваносу файла часткамі), і Bidirectional Streaming (абе стороны неперывна перадаюць дадзеныя адна другай, што падходзіць для функцый саўместнай роботы у рэальны час).
Калі ўжываць яго: для пераказу дадзенняў межаў служб у самай вашай інфраструктуре, дзе важлівыя швальнасць і строгая типавасць. У будзь-якім месца, дзе вашы службы адмашчаюць вялікі обсяг запитоў, а парсаванне JSON стае значным выклікам.
Калі не ўжываць яго: для API, доступныя публіцы і выкарыстоўваныя браузерамі чы розробнікамі званаўнай стороны. Бінарная прырода Protobuf значна ускладнюе ўтрыманне та дыбаггін, а ўстановка яго для роботы в браузеры выклікае дадатковыя настройкі. Для всего, што спрямавана да корыстнікаў, REST застаецца болей практычным выборам.
SOAP: Строгі, деталізаваны, але яшчэ і сьведчае пра роль банкаў
SOAP (Simple Object Access Protocol) быў створаны ў 1998 году, таму ён старэйшы за сам REST. Большасць сучасных разработчыкаў сталкнуліся з яным толькі пад час падключэння да банкавых систем, платформ для страхавання чыя большых корпоратыўных програм — галузей, якія рана адразу застосавалі SOAP і ніколи не мелі сэрьозных прычын для пераходу на іншыя тэхналогіі.
SOAP не ўможлівае гнучкасці. Кожная паведамленне ў яму — это XML, упакованы ў строго адзначаную структуру. Хоця REST дае великі прыгон у тым, як форматаваць даны, SOAP выказвае трэбуху, каб обе стороны прыдзержваліся точна вяліканага, заздалегідь заданага шаблона.
<!-- Every SOAP message follows this envelope structure -->
<Envelope>
<Header>
<Security><!-- authentication goes here --></Security>
</Header>
<Body>
<GetAccountBalance>
<AccountId>ACC123</AccountId>
</GetAccountBalance>
</Body>
</Envelope>
Такая моцная структура існуе спецыяльна. Стандарт WS-Security для SOAP аб’еднвае аутентыкацію, цифровыя падпісы і шфаруванне ў аднае паведамленне. Для фінансовых транзакцый, дзе будь-якія змены пад час перавозкі могу спрычыніць серйозныя нашкоды, такі вбудованы слой захавы прабачае дадзеную вагу.
Калі ўжываць яго: для з’яўлення ў спецыяльным інтерфейсе банку, платежнай системе, якая выклікае викорыстанне SOAP, дзяржавных системах, платформах страхавання або будзь-якіх старэйшых корпатыўных системах, якія адкрываюць толькі інтерфейс SOAP. Малая верасць, што вы выберазеце SOAP для проекта, які ствараеце з нуля, але розумэнне яго є важлівым, калі трэба сумесна працаваць з системамі, побудованымі на яго аднойчы.
Калі не ўжываць яго: у новых проектах, дзе вы контролюеце обе стороны вялікання дадзеных. Рэалізацыя SOAP займае больш часу, його XML-пакеты ускладнююць аналіз каштоўных памылак, і ён не мае перавагаў перед REST або gRPC, калі сумеснае працаванне з старымі системамі больш не ёсць працэйскай патрэбой.
Карта выбору
Іспользуйце гэта як швыракі паводак для выбору правильнага інструмента:
Стандартныя веб-з’яданні або API, які ўжываюцца для спрацоўвання з публікай, выкарыстоваюць протакол REST. Мобільныя дапыткі, якім патрэбны гнучкія даны, прыстосаваныя да конкрэтных задач, выкарыстоваюць протакол GraphQL. Дзяўны чат, мнагаадресаваныя взаімадзеі або практычна мгновенныя упавядомленні выкарыстоваюць WebSockets. Падтверджэння платежаў і запуск процесаў CI/CD выкарыстоваюць Webhooks. Внутрашняе мікросервісы, якім патрэбна высока скорасць, выкарыстоваюць протакол gRPC. Банкавыя системы і інтеграціі старых корпоратыўных рашэнняў выкарыстоваюць протакол SOAP.
Што вы тепер разумеете
REST застаецца стандартным выборам. Усі іншы патэрны ствараны для выправлення адзінаковых недагоўдаў, калі REST не падходзіць: GraphQL выкорыстоўваецца, калі патрэбныя даны разлічаюцца залежна ад кліента; WebSockets — калі неабходна паставіць з’яўленне на адночасны роўны ў обох направленнях; Webhooks — калі трэба реагаваць на здарынкі, а не постаўляць сталы запит пра яны; gRPC — калі JSON становіцься занадта медленным для внутрашняго трафіку служб; а SOAP — калі трэбаванні да безпекі на рэвэльскам роўні не залешаюць іншых варыянтаў.
Калі наступны раз будзеце проектаваць інтэграцыю, не пачынайце з запитання, як прымусіць выкарыстоўваць REST. Узамест таго запытайце, який патэрн камунікацыі на самай працоўны адпавядае таму, што трэба зробіць системе. Гэтай адпаведзі ўжо павінна вяліць за выбор адпаведнага інструмента, а не прыzwычка.
Як наступны крок, выберыце аднаго з гэтых шаблонаў, з якім вы ўсё ўжо не працавалі. Знайдзіце яго афіцыйную дакументацыю чы ўжо маленькі проект на адкрытым кодзе, пабудованы на ям, і прачытайце рэальную рэалізацыю, прычаму ўжо да таго часу, калі вас змусяць стварыць такі шаблон пад тым прытыскам.