REST API vs Webhook: Stop Asking "Are We There Yet?" ππ¨
If you've been building applications for a while, you've probably worked with REST APIs.
And at some point, you've probably written something like this:
setInterval(() => {
checkStatus();
}, 5000);
Congratulations. π
You've successfully taught your application to behave like a kid on a road trip:
"Are we there yet?"
"No."
"Are we there yet?"
"No."
"How about now?"
That's basically polling. π
And this is exactly where Webhooks enter the picture.
Let's understand REST APIs vs Webhooks without making it feel like we're reading an RFC document.
π Let's Start With Pizza
Imagine you've ordered a pizza.
You have two ways to know whether it's ready.
REST API Approach
You call the restaurant every 2 minutes.
π©βπ» You: "Is my pizza ready?"
π Restaurant: "No."
Two minutes later...
π©βπ» You: "Now?"
π Restaurant: "Still no."
Two minutes later...
π©βπ» You: "Now?"
π Restaurant: "Please stop calling us."
Finally...
π©βπ» You: "Now?"
π Restaurant: "YES!"
This is essentially polling an API.
Your application keeps asking the server whether something has changed.
Webhook Approach
Now imagine a slightly smarter restaurant.
You order the pizza and continue watching Netflix.
When the pizza is ready:
π Ding Dong!
The restaurant notifies you.
You didn't ask.
You didn't poll.
You didn't write a setInterval().
You just got notified when something happened.
That's a Webhook.
So, What Exactly Is a REST API?
REST stands for Representational State Transfer.
Which sounds complicated enough to impress someone at a meeting.
But the idea is simple.
A client sends a request.
The server sends a response.
Client
β
β GET /orders/123
βΌ
Server
β
β 200 OK
βΌ
{
"status": "Shipped"
}
The important part is:
The client starts the conversation.
The server isn't randomly calling your frontend at 2 AM saying:
"HEY! ORDER 123 JUST SHIPPED!"
It waits until you ask.
Common REST Methods
| Method | Meaning |
|---|---|
GET |
Give me something |
POST |
Create something |
PUT |
Replace something |
PATCH |
Change something |
DELETE |
This relationship isn't working |
Okay... technically DELETE removes a resource. π
Example REST Request
GET /api/users/101
Response:
{
"id": 101,
"name": "Alex",
"role": "Developer"
}
Simple.
Predictable.
Reliable.
REST APIs are perfect when you know when you need the data.
What Is a Webhook?
A Webhook flips the communication model.
Instead of:
"Hey server, anything new?"
The server says:
"I'll tell you when something happens."
Your application exposes an endpoint:
POST /webhooks/payment
Then another service calls it when an event occurs.
For example:
{
"event": "payment.completed",
"orderId": 1234,
"amount": 250
}
Your application didn't ask for this.
The payment provider sent it because something happened.
That's why Webhooks are often described as:
Event-driven HTTP callbacks.
Or, if you prefer:
"Call me when something interesting happens."
REST API vs Webhook Communication
REST API
Client Server
β β
βββββ Anything new? ββββββββΊβ
ββββββββ Nope βββββββββββββββ
β β
βββββ Anything new? ββββββββΊβ
ββββββββ Still nope βββββββββ
β β
βββββ Anything new? ββββββββΊβ
ββββββββ YES! βββββββββββββββ
Webhook
Application Provider
β β
β β
β *event occurs* β
β β
ββββββ HEY! UPDATE! ββββββββ
β β
βββββββ 200 OK ββββββββββββΊβ
Much quieter.
Your servers will thank you.
Your cloud bill might too. π
Polling vs Push
Let's say you're waiting for a payment to complete.
Polling
GET /payment/status
Pending
Five seconds later:
GET /payment/status
Pending
Again:
GET /payment/status
Pending
Again:
GET /payment/status
Pending
Again:
GET /payment/status
Success
Your server:
"You could've just waited for me to tell you." π
Webhook
Payment succeeds.
The payment provider immediately sends:
{
"event": "payment.success",
"paymentId": "pay_123"
}
Your application processes it.
Done.
No unnecessary requests.
No polling.
No server harassment.
Real-World Example: GitHub π»
Imagine building CI/CD without Webhooks.
Your CI server would constantly ask:
Hey GitHub, new commit?
No.
New commit?
No.
New commit?
No.
New commit?
YES!
Instead, when someone pushes code, GitHub sends a Webhook.
{
"event": "push",
"repository": "awesome-project",
"branch": "main"
}
Your pipeline wakes up and starts working.
Meanwhile, the developer who pushed on Friday evening suddenly remembers:
"Maybe I shouldn't have deployed that."
Too late. π
Real-World Example: Payments π³
Payment systems are one of the best examples of why Webhooks matter.
Your application might initiate a payment using a REST API.
POST /payments
The payment provider responds:
{
"paymentId": "12345",
"status": "processing"
}
But the final payment result may happen secondsβor minutesβlater.
Instead of repeatedly checking:
GET /payments/12345
GET /payments/12345
GET /payments/12345
The provider sends:
{
"event": "payment.completed",
"paymentId": "12345"
}
REST started the process.
Webhook told us how it ended.
A beautiful relationship. β€οΈ
Unlike some microservices.
Real-World Example: WhatsApp Business π¬
Messaging systems are another perfect example.
Your application sends a message using an API.
POST /messages
The message may go through multiple states:
Sent
β
Delivered
β
Read
You don't want to keep asking:
Is it delivered?
Is it delivered?
Is it delivered?
Did they read it?
Did they read it?
WHY HAVEN'T THEY READ IT?!
At this point, we're no longer debugging.
We're emotionally invested. π
Instead, Webhooks notify your application whenever the status changes.
{
"status": "delivered"
}
Later:
{
"status": "read"
}
Your application updates accordingly.
REST APIs Are Great At...
REST APIs are ideal when your application needs to actively perform an operation.
For example:
- Fetch users
- Search products
- Create orders
- Update profiles
- Delete records
- Generate reports
Think:
"I need something right now."
Use an API.
Webhooks Are Great At...
Webhooks are ideal when your application needs to react when something happens.
For example:
- Payment completed
- Order shipped
- Message delivered
- Email opened
- User registered
- GitHub push received
- Build completed
Think:
"Tell me when something happens."
Use a Webhook.
REST API vs Webhook
| Feature | REST API | Webhook |
|---|---|---|
| Communication | Request β Response | Event β Notification |
| Initiated By | Client | Provider |
| Updates | Polling | Push |
| Real-Time | Not necessarily | Usually |
| HTTP Methods | GET, POST, PUT, PATCH, DELETE | Mostly POST |
| Best For | CRUD & commands | Event notifications |
| Network Requests | Potentially many | Usually only when needed |
| Endpoint | Provider exposes API | Consumer exposes endpoint |
| Developer Mood | π | π |
Okay, that last row may not be scientifically verified.
Why Not Use Webhooks for Everything?
At this point, Webhooks might sound magical.
So why not replace APIs completely?
Because imagine asking:
"Webhook, give me all products under βΉ1,000."
Webhook:
"That's... not my job."
Webhooks notify you about events.
They aren't designed for arbitrary data retrieval.
Similarly, REST APIs don't magically notify you when something changes unless you ask.
They solve different problems.
The Best Architecture? Use Both π€
Most modern integrations use REST APIs and Webhooks together.
For example:
USER
β
β
βΌ
REST API Request
Create Order
β
βΌ
Application
β
βΌ
Payment Provider
β
β
Payment Completed
β
βΌ
WEBHOOK
β
βΌ
Update Database
β
βΌ
Notify Customer
REST API:
"Please do this."
Webhook:
"Hey! That thing you asked for? It's done."
But Webhooks Come With Responsibilities β οΈ
Webhooks are great, but don't blindly trust incoming requests.
Anyone who discovers your endpoint could potentially send requests to it.
POST /webhook
{
"payment": "success"
}
Your application:
"Cool! Free money!"
π¨ Absolutely not.
Always verify incoming Webhooks.
Common protections include:
- HTTPS
- HMAC signatures
- Secret tokens
- Timestamp validation
- Replay protection
- Idempotency
- Retry handling
Don't Forget Idempotency
Webhook providers may retry events.
That means you might receive:
payment.completed
twice.
If your code blindly processes both:
Webhook #1 β Ship Product
Webhook #2 β Ship Product Again
Customer:
"Wow, amazing service!"
Finance team:
"We need to talk."
Your Webhook handlers should therefore be idempotent.
Processing the same event multiple times should produce the same result as processing it once.
What Happens If Your Webhook Fails?
Suppose the provider sends:
POST /webhook
But your server responds:
500 Internal Server Error
Most Webhook providers implement retry mechanisms.
Something like:
Attempt 1 β Failed
Wait...
Attempt 2 β Failed
Wait longer...
Attempt 3 β Success π
This is commonly implemented using exponential backoff.
So when designing Webhooks, always think about:
- Retries
- Duplicate events
- Event ordering
- Failed processing
- Logging and monitoring
Because distributed systems have one universal rule:
If something can fail, eventually it will.
Usually in production.
Usually on Friday.
Quick Decision Guide
Ask yourself one question.
Do I need to request something?
YES
β
βΌ
REST API
Examples:
Get Products
Create Order
Update User
Delete Record
Do I need to know when something happens?
YES
β
βΌ
WEBHOOK
Examples:
Payment Completed
Order Shipped
Message Delivered
Build Finished
Need both?
Welcome to modern software development. π
Final Takeaway
The easiest way to remember the difference is:
REST API
"Hey, do you have an update?"
Webhook
"I'll call you when I have an update."
REST APIs are request-driven.
Webhooks are event-driven.
And in most real-world systems, they work best together.
So the next time you find yourself writing:
setInterval(checkStatus, 5000);
Pause for a second.
Take a deep breath.
And ask:
"Could this have been a Webhook?" π
If you enjoyed this article, drop a β€οΈ, share it with another developer, and let me know:
What's the funniest polling implementation you've seen in production? π
Happy Coding! π
Top comments (0)