Wybierz API gdy
- Potrzebujesz danych na zadanie
- Klient może być offline
- Dane zmieniaja się rzadko
- Potrzebujesz pełnej kontroli nad momentem pobierania
- Integrujesz z systemem bez wsparcia webhookow
W komunikacji miedzy systemami wyrozniamy dwa fundamentalne modele: pull (klient pyta serwer) i push (serwer powiadamia klienta). API REST reprezentuje model pull, natomiast webhooki realizuja model push. Zrozumienie różnic miedzy nimi pozwala projektowac wydajne i responsywne systemy integracyjne.
API to interfejs umozliwiajacy komunikacje miedzy aplikacjami. W kontekscie webowym najczesciej mowimy o REST API lub GraphQL - endpointach HTTP, które klient może wywoływać, aby pobrać lub zmodyfikować dane.
Model działania: Pull (request-response)
Webhook (nazywany też callback URL lub HTTP callback) to mechanizm, w którym serwer automatycznie wysyła dane do klienta, gdy wystapi okreslone zdarzenie.
Model działania: Push (event-driven)
┌────────┐ ┌────────┐│ Klient │ ───── Request ─────> │ Serwer ││ │ <──── Response ───── │ │└────────┘ └────────┘
Przykład: "Czy sa nowe zamowienia?"- Klient pyta co 5 sekund- Serwer odpowiada: "Nie" / "Tak, oto dane"┌────────┐ ┌────────┐│ Klient │ <── Webhook POST ─── │ Serwer ││ │ ──── Ack 200 OK ───> │ │└────────┘ └────────┘
Przykład: "Powiadom mnie o nowych zamowieniach"- Klient rejestruje URL webhooka- Serwer wysyła POST, gdy pojawi się zamowienie- Klient przetwarza dane natychmiastPolling (nieefektywny):
Czas: 0s 5s 10s 15s 20s 25s 30sKlient: ? ? ? ? ? ? ?Serwer: - - - ! - - - └─────────────────┴─────────────────┘ 6 pustych zapytan, 1 z danymiWebhook (efektywny):
Czas: 0s 5s 10s 15s 20s 25s 30sKlient: (czeka) !Serwer: (przetwarza) └── Wysyła webhook Zero pustych zapytan, natychmiastowa reakcja// Klient odpytuje API co 10 sekund (polling)async function checkForNewOrders() { const response = await fetch('https://api.sklep.pl/orders?status=new', { headers: { 'Authorization': 'Bearer ' + apiKey } }); const orders = await response.json();
if (orders.length > 0) { processOrders(orders); }}
// Polling - nieefektywne, ale prostesetInterval(checkForNewOrders, 10000);Rejestracja webhooka (jednorazowo):
// Rejestracja URL webhooka w systemie zewnetrznymawait fetch('https://api.sklep.pl/webhooks', { method: 'POST', headers: { 'Authorization': 'Bearer ' + apiKey, 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://moja-aplikacja.pl/webhooks/orders', events: ['order.created', 'order.paid'] })});Endpoint odbierajacy webhook (serwer klienta):
// Express.js - endpoint odbierajacy webhookiapp.post('/webhooks/orders', express.json(), (req, res) => { const signature = req.headers['x-webhook-signature'];
// Weryfikacja podpisu (bezpieczeństwo!) if (!verifySignature(req.body, signature, webhookSecret)) { return res.status(401).send('Invalid signature'); }
const event = req.body; console.log('Otrzymano event:', event.type);
// Przetwarzanie zdarzenia switch (event.type) { case 'order.created': handleNewOrder(event.data); break; case 'order.paid': handlePayment(event.data); break; }
// Potwierdzenie odbioru (WAZNE!) res.status(200).send('OK');});{ "id": "evt_123456789", "type": "order.created", "created_at": "2024-01-15T10:30:00Z", "data": { "order_id": "ord_abc123", "customer_email": "klient@example.com", "total": 199.99, "currency": "PLN", "items": [ { "product_id": "prod_xyz", "name": "Kurs programowania", "quantity": 1 } ] }}| Aspekt | API (Pull) | Webhook (Push) |
|---|---|---|
| Inicjator | Klient | Serwer |
| Opoznienie | Zależne od czestotliwosci pollingu | Natychmiastowe |
| Obciazenie sieci | Wysokie (wiele pustych zapytan) | Niskie (tylko gdy jest zdarzenie) |
| Złożoność klienta | Prostsza (aktywne odpytywanie) | Wymaga serwera HTTP |
| Niezawodnosc | Wysoka (klient kontroluje) | Wymaga retry mechanism |
| Dostepnosc | Klient może być offline | Klient musi być online |
| Bezpieczeństwo | Standardowe tokeny | Wymaga weryfikacji podpisow |
Wybierz API gdy
Wybierz Webhook gdy