Complete Guide to API Types with Examples

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

  • Stateless: Each request contains all necessary information
  • Uses HTTP Methods: GET, POST, PUT, DELETE, PATCH
  • Resource-based: URLs represent resources
  • Multiple formats: Usually JSON, but can use XML

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

  • E-commerce platforms (Shopify, Amazon)
  • Social media integrations
  • Weather services (OpenWeatherMap)
  • Payment processing (Stripe)
  • Cloud storage (Dropbox, Google Drive)


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

  • Protocol-based: Strict standards (WS-Security, WS-ReliableMessaging)
  • XML only: All messages in XML format
  • WSDL: Web Services Description Language for API documentation
  • Built-in error handling: Standardized fault messages

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

  • Banking and financial services
  • Healthcare systems (HL7 integration)
  • Government services
  • Enterprise resource planning (ERP) systems
  • Telecom services


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

  • Single endpoint: Usually /graphql
  • Client-specified queries: Frontend defines data requirements
  • Strongly typed: Schema-based with type validation
  • No over-fetching/under-fetching: Get exactly what you ask for

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

  • Mobile applications with varying data needs
  • Single-page applications (SPAs)
  • Microservices aggregation
  • Real-time dashboards
  • Used by: Facebook, Shopify, GitHub, Airbnb


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

  • HTTP/2: Multiplexing, streaming, header compression
  • Protocol Buffers: Compact binary serialization
  • Language agnostic: Code generation for multiple languages
  • 4 types: Unary, Server streaming, Client streaming, Bidirectional streaming

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)

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

  • Microservices architecture
  • Real-time communication systems
  • IoT device communication
  • Mobile backends (low bandwidth)
  • Internal APIs in distributed systems
  • Used by: Google, Netflix, Square


5. WebSocket API

Overview

WebSocket provides full-duplex communication channels over a single TCP connection, enabling real-time bidirectional data flow.

Key Characteristics

  • Persistent connection: Stays open unlike HTTP
  • Bidirectional: Server and client can send data anytime
  • Low latency: No overhead of repeated HTTP handshakes
  • Real-time: Instant data push without polling

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

  • Real-time chat applications (Slack, WhatsApp Web)
  • Live sports scores and updates
  • Stock trading platforms
  • Multiplayer online games
  • Collaborative editing tools (Google Docs)
  • Live streaming comments
  • IoT dashboards


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

  • Event-driven: Triggered by specific events
  • Push-based: Server sends data to client
  • HTTP POST: Usually sends data via POST request
  • Asynchronous: Non-blocking communication

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

  • Payment notifications (Stripe, PayPal, Square)
  • CI/CD triggers (GitHub, GitLab, Jenkins)
  • Email delivery events (SendGrid, Mailgun)
  • Order status updates (Shopify, WooCommerce)
  • Form submissions (Typeform, Google Forms)
  • Calendar events (Google Calendar, Outlook)
  • CRM updates (Salesforce, HubSpot)


Comparison Summary

Article content

Choosing the Right API

Choose REST when:

  • Building public APIs
  • Need simple, stateless communication
  • Want broad compatibility

Choose SOAP when:

  • Need enterprise-level security
  • Require ACID transactions
  • Working with legacy systems

Choose GraphQL when:

  • Frontend needs vary significantly
  • Want to reduce network requests
  • Need flexible data fetching

Choose gRPC when:

  • Building microservices
  • Need high performance
  • Working with polyglot environments

Choose WebSocket when:

  • Need real-time bidirectional communication
  • Building chat, gaming, or live applications
  • Want persistent connections

Choose Webhook when:

  • Need event-driven architecture
  • Want to avoid polling
  • Integrating with third-party services

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.

To view or add a comment, sign in

More articles by Raajeev H Dave

Others also viewed

Explore content categories