Complete Guide to API Types with Examples
1. REST API (Representational State Transfer)
Overview
REST is an architectural style that uses HTTP methods to interact with resources. It's the most widely used API type due to its simplicity and scalability.
Key Characteristics
Real-World Example: Twitter API
Get User Tweets
GET https://api.twitter.com/2/users/12345/tweets
Authorization: Bearer YOUR_ACCESS_TOKEN
Response:
{
"data": [
{
"id": "1234567890",
"text": "Hello World!",
"created_at": "2025-10-05T10:30:00Z"
}
]
}
Create a Tweet
POST https://api.twitter.com/2/tweets
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"text": "My first tweet via API!"
}
Response:
{
"data": {
"id": "9876543210",
"text": "My first tweet via API!"
}
}
Use Cases
2. SOAP API (Simple Object Access Protocol)
Overview
SOAP is a protocol-based API that uses XML for message format. It's highly structured and includes built-in security features.
Key Characteristics
Real-World Example: Payment Gateway
Request: Process Payment
POST /payment-service
Content-Type: text/xml
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Authentication>
<Username>merchant123</Username>
<Password>secure_pass</Password>
</Authentication>
</soap:Header>
<soap:Body>
<ProcessPayment>
<Amount>100.00</Amount>
<Currency>USD</Currency>
<CardNumber>4111111111111111</CardNumber>
<ExpiryDate>12/26</ExpiryDate>
</ProcessPayment>
</soap:Body>
</soap:Envelope>
Response: Payment Confirmation
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProcessPaymentResponse>
<TransactionId>TXN-789456123</TransactionId>
<Status>Success</Status>
<Timestamp>2025-10-05T10:35:00Z</Timestamp>
</ProcessPaymentResponse>
</soap:Body>
</soap:Envelope>
Use Cases
3. GraphQL
Overview
GraphQL is a query language that allows clients to request exactly the data they need, nothing more and nothing less.
Key Characteristics
Real-World Example: GitHub API
Query: Get User and Repository Data
POST https://api.github.com/graphql
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"query": "query {
user(login: \"octocat\") {
name
bio
repositories(first: 3) {
nodes {
name
description
stargazerCount
primaryLanguage {
name
}
}
}
}
}"
}
Response
{
"data": {
"user": {
"name": "The Octocat",
"bio": "GitHub's mascot",
"repositories": {
"nodes": [
{
"name": "Hello-World",
"description": "My first repository",
"stargazerCount": 1523,
"primaryLanguage": {
"name": "JavaScript"
}
},
{
"name": "Spoon-Knife",
"description": "Test repo",
"stargazerCount": 892,
"primaryLanguage": {
"name": "HTML"
}
}
]
}
}
}
}
Mutation: Create Repository
mutation {
createRepository(input: {
name: "my-new-project"
description: "A cool new project"
visibility: PUBLIC
}) {
repository {
id
name
url
}
}
}
Use Cases
4. gRPC (Google Remote Procedure Call)
Overview
gRPC is a high-performance RPC framework that uses Protocol Buffers for serialization and HTTP/2 for transport.
Key Characteristics
Real-World Example: Microservices Communication
Protocol Buffer Definition (user.proto)
syntax = "proto3";
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
rpc ListUsers (ListUsersRequest) returns (stream UserResponse);
}
message UserRequest {
string user_id = 1;
}
message UserResponse {
string user_id = 1;
string name = 2;
string email = 3;
int32 age = 4;
}
message ListUsersRequest {
int32 page_size = 1;
}
Server Implementation (Python)
Recommended by LinkedIn
import grpc
import user_pb2
import user_pb2_grpc
class UserService(user_pb2_grpc.UserServiceServicer):
def GetUser(self, request, context):
# Fetch user from database
return user_pb2.UserResponse(
user_id=request.user_id,
name="John Doe",
email="john@example.com",
age=30
)
def ListUsers(self, request, context):
# Stream multiple users
for user in get_users_from_db(request.page_size):
yield user_pb2.UserResponse(
user_id=user.id,
name=user.name,
email=user.email,
age=user.age
)
Client Call (Python)
import grpc
import user_pb2
import user_pb2_grpc
# Create channel and stub
channel = grpc.insecure_channel('localhost:50051')
stub = user_pb2_grpc.UserServiceStub(channel)
# Make unary call
request = user_pb2.UserRequest(user_id="12345")
response = stub.GetUser(request)
print(f"User: {response.name}, Email: {response.email}")
# Stream responses
request = user_pb2.ListUsersRequest(page_size=10)
for user in stub.ListUsers(request):
print(f"User: {user.name}")
Use Cases
5. WebSocket API
Overview
WebSocket provides full-duplex communication channels over a single TCP connection, enabling real-time bidirectional data flow.
Key Characteristics
Real-World Example: Chat Application
Client Connection (JavaScript)
// Establish WebSocket connection
const socket = new WebSocket('wss://chat.example.com/ws');
// Connection opened
socket.addEventListener('open', (event) => {
console.log('Connected to chat server');
// Send authentication
socket.send(JSON.stringify({
type: 'auth',
token: 'user_auth_token'
}));
});
// Listen for messages
socket.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
switch(data.type) {
case 'message':
displayMessage(data.user, data.text, data.timestamp);
break;
case 'user_joined':
showNotification(`${data.user} joined the chat`);
break;
case 'typing':
showTypingIndicator(data.user);
break;
}
});
// Send a message
function sendMessage(text) {
socket.send(JSON.stringify({
type: 'message',
text: text,
timestamp: Date.now()
}));
}
// Send typing indicator
function notifyTyping() {
socket.send(JSON.stringify({
type: 'typing',
user_id: currentUserId
}));
}
// Handle connection close
socket.addEventListener('close', (event) => {
console.log('Disconnected from chat server');
// Implement reconnection logic
});
// Handle errors
socket.addEventListener('error', (error) => {
console.error('WebSocket error:', error);
});
Server Implementation (Node.js with ws library)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
const clients = new Map();
wss.on('connection', (ws) => {
let userId = null;
ws.on('message', (message) => {
const data = JSON.parse(message);
switch(data.type) {
case 'auth':
userId = authenticateUser(data.token);
clients.set(userId, ws);
// Notify others
broadcast({
type: 'user_joined',
user: userId
}, userId);
break;
case 'message':
// Broadcast message to all clients
broadcast({
type: 'message',
user: userId,
text: data.text,
timestamp: data.timestamp
});
break;
case 'typing':
// Notify others user is typing
broadcast({
type: 'typing',
user: userId
}, userId);
break;
}
});
ws.on('close', () => {
if (userId) {
clients.delete(userId);
broadcast({
type: 'user_left',
user: userId
});
}
});
});
function broadcast(data, excludeUserId = null) {
const message = JSON.stringify(data);
clients.forEach((client, id) => {
if (id !== excludeUserId && client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
}
Use Cases
6. Webhook
Overview
Webhooks are user-defined HTTP callbacks triggered by specific events. Instead of polling for changes, the server pushes data to your application when events occur.
Key Characteristics
Real-World Example: Payment Notification (Stripe)
Setting Up Webhook
// Register webhook endpoint in Stripe Dashboard
// URL: https://myapp.com/webhooks/stripe
// Events: payment_intent.succeeded, payment_intent.failed
Webhook Receiver (Node.js/Express)
const express = require('express');
const stripe = require('stripe')('sk_test_...');
app.post('/webhooks/stripe', express.raw({type: 'application/json'}), async (req, res) => {
const sig = req.headers['stripe-signature'];
const webhookSecret = 'whsec_...';
let event;
try {
// Verify webhook signature
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
} catch (err) {
console.log('Webhook signature verification failed:', err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log(`Payment ${paymentIntent.id} succeeded!`);
// Update database
await updateOrderStatus(paymentIntent.metadata.order_id, 'paid');
// Send confirmation email
await sendConfirmationEmail(paymentIntent.receipt_email);
// Update inventory
await updateInventory(paymentIntent.metadata.order_id);
break;
case 'payment_intent.payment_failed':
const failedPayment = event.data.object;
console.log(`Payment ${failedPayment.id} failed`);
// Notify user of failure
await sendPaymentFailureEmail(failedPayment.receipt_email);
// Log for review
await logFailedPayment(failedPayment);
break;
case 'customer.subscription.deleted':
const subscription = event.data.object;
// Cancel user's subscription in database
await cancelSubscription(subscription.customer);
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
// Return 200 to acknowledge receipt
res.json({received: true});
});
Example Webhook Payload from Stripe
{
"id": "evt_1234567890",
"object": "event",
"type": "payment_intent.succeeded",
"created": 1696512000,
"data": {
"object": {
"id": "pi_1234567890",
"amount": 2000,
"currency": "usd",
"status": "succeeded",
"receipt_email": "customer@example.com",
"metadata": {
"order_id": "ORDER-12345",
"customer_name": "John Doe"
}
}
}
}
GitHub Webhook Example: Repository Push
// Webhook endpoint for GitHub
app.post('/webhooks/github', (req, res) => {
const event = req.headers['x-github-event'];
const payload = req.body;
if (event === 'push') {
console.log(`Push to ${payload.repository.name}`);
console.log(`Branch: ${payload.ref}`);
console.log(`Commits: ${payload.commits.length}`);
// Trigger CI/CD pipeline
triggerBuild({
repo: payload.repository.name,
branch: payload.ref,
commit: payload.head_commit.id,
author: payload.head_commit.author.name
});
// Send notification to team
notifyTeam({
message: `New push by ${payload.pusher.name}`,
commits: payload.commits.map(c => c.message)
});
}
res.status(200).send('Webhook received');
});
Use Cases
Comparison Summary
Choosing the Right API
Choose REST when:
Choose SOAP when:
Choose GraphQL when:
Choose gRPC when:
Choose WebSocket when:
Choose Webhook when:
This reminds me of that Stack Overflow survey finding that REST APIs are used by over 80% of developers, making it the most widely adopted API architecture. Your comprehensive examples perfectly demonstrate why REST dominates while showing when alternatives like GraphQL or gRPC might be better choices for specific scenarios.