API AUTOMATIONADVANCED

Playwright Backend Testing Tutorial – REST API, GraphQL, WebSocket, Kafka, Database & Microservices

Learn backend testing with Playwright step by step. Understand microservices, REST APIs, GraphQL, WebSockets, Kafka, Pub/Sub, messaging, database validation, and how to build enterprise end-to-end Playwright tests.

iff Solution Academy September 4, 2026 30 min read Updated September 4, 2026
Playwright Backend Testing REST API GraphQL WebSocket Kafka Microservices Database Testing Event-Driven Testing SDET Quality Engineering

Modern applications are no longer just a browser connected to a single API. An enterprise application may contain a web or mobile frontend, backend services, microservices, REST APIs, GraphQL APIs, WebSockets, databases, Kafka or another message broker, topics, publishers and consumers, and event-driven workflows.

For a modern SDET, testing only the UI or checking that an API returns 200 OK is often not enough. Playwright can be used as part of a broader Quality Engineering architecture where one test project validates the application across multiple layers:

text
UI
 ↓
REST / GraphQL
 ↓
Microservices
 ↓
Database
 ↓
Messaging / Kafka
 ↓
WebSocket Events
 ↓
UI

This tutorial explains these technologies from a Playwright testing perspective and then shows how they can be organized into one professional automation framework.

1. Understanding the Modern Application Architecture

Consider an e-commerce application:

text
                         React UI
                            │
                ┌───────────┴───────────┐
                │                       │
             REST API                GraphQL
                │                       │
                └───────────┬───────────┘
                            ▼
                         Backend
                            │
          ┌─────────────────┼─────────────────┐
          ▼                 ▼                 ▼
    Product Service    Order Service     User Service
          │                 │                 │
          ▼                 ▼                 ▼
      Product DB         Order DB           User DB

                            │
                            │ Publish Events
                            ▼
                     Message Broker
                            │
                         Topics
                            │
              ┌─────────────┼─────────────┐
              ▼             ▼             ▼
          Inventory       Email       Analytics
          Consumer       Consumer      Consumer

                            │
                            ▼
                       WebSocket
                            │
                            ▼
                     Real-Time UI

These technologies solve different problems. They are not replacements for one another.

2. What Is a Backend?

The backend is the server-side part of an application. It commonly handles:

  • Business logic
  • Authentication
  • Authorization
  • Database operations
  • API processing
  • Integrations
  • Messaging
  • Calculations
  • Validation

For example:

text
Browser

   │
   │ GET /products/100
   ▼

Backend

   │
   ├── Validate request
   ├── Check authorization
   ├── Execute business logic
   ├── Query database
   └── Build response

   ▼

200 OK

A frontend displays information. The backend determines how much of that information is created, retrieved, validated, transformed, and stored.

3. What Is a Microservice?

A traditional application may contain most backend functionality inside one application. This is generally called a monolithic architecture.

text
             Backend

    Users
    Products
    Orders
    Payments
    Inventory

      One Application

A microservices architecture separates major capabilities into independently deployable services.

text
                 Application
                      │
       ┌──────────────┼──────────────┐
       ▼              ▼              ▼
 Product Service  Order Service  Payment Service
       │              │              │
       ▼              ▼              ▼
 Product DB        Order DB       Payment DB
text
Product Service
- create product
- retrieve product
- update product
- inventory information

Order Service
- create order
- cancel order
- order status

Payment Service
- payment
- refund
- payment status

Microservices can communicate using REST, GraphQL, messaging, or other protocols.

How should an SDET test a microservice?

A professional strategy usually includes:

text
Unit
 ↓
Component
 ↓
API
 ↓
Contract
 ↓
Integration
 ↓
End-to-End

You should test both the service itself and its interactions with dependent systems. For example, an Order Service may depend on a Payment Service, an Inventory Service, an Order Database, and Kafka.

Important scenarios include:

  • Successful order
  • Payment declined
  • Inventory unavailable
  • Dependency timeout
  • Database failure
  • Duplicate request
  • Invalid request
  • Unauthorized request
  • Event publishing failure

4. What Is an API?

An API — Application Programming Interface — provides a defined interface through which software systems communicate.

text
React UI
   │
   │ API
   ▼
Product Service
   │
   ▼
PostgreSQL

The browser does not need to know how the database works. It can request GET /products/100 and receive:

json
{
  "id": 100,
  "name": "Laptop",
  "price": 1499
}

The API acts as the interface between the systems.

5. REST API and HTTP

REST is a common architectural style used to build web APIs. A product API might expose:

text
GET    /products
GET    /products/{id}
POST   /products
PUT    /products/{id}
PATCH  /products/{id}
DELETE /products/{id}

REST APIs commonly communicate using HTTP. Common HTTP methods:

  • GET — Retrieve
  • POST — Create/process
  • PUT — Replace/update
  • PATCH — Partial update
  • DELETE — Delete
http
POST /products
Content-Type: application/json

{
  "name": "MacBook Pro",
  "price": 1999
}

Possible response: 201 Created.

6. REST API Testing with Playwright

Playwright includes API testing capabilities through APIRequestContext.

tests/api/product.spec.ts
import { test, expect } from '@playwright/test';

test('get product', async ({ request }) => {

  const response = await request.get(
    '/products/100'
  );

  expect(response.status()).toBe(200);

  const product = await response.json();

  expect(product.id).toBe(100);
  expect(product.name).toBeDefined();
  expect(product.price).toBeGreaterThan(0);

});

Do not stop at expect(response.status()).toBe(200). A professional REST test should consider:

  • Status code
  • Response payload
  • Headers
  • Schema
  • Authentication
  • Authorization
  • Business rules
  • Invalid input
  • Boundary values
  • Database state
  • Response time
  • Downstream behavior

REST CRUD Workflow

A useful automated workflow is:

text
POST
Create Product
     ↓
Capture ID
     ↓
GET
Validate Product
     ↓
PATCH
Update Product
     ↓
GET
Validate Changes
     ↓
DELETE
Delete Product
     ↓
GET
Expect 404

This tests the lifecycle of the resource instead of isolated endpoints.

7. What Is GraphQL?

GraphQL provides another approach to API communication. With REST (GET /products/100), the server determines the shape of the response. GraphQL allows the client to request specific fields.

graphql
query {
  product(id: 100) {
    id
    name
    price
  }
}

Response:

json
{
  "data": {
    "product": {
      "id": 100,
      "name": "Laptop",
      "price": 1499
    }
  }
}

The three important GraphQL operations are:

  • Query — retrieve data
  • Mutation — change data
  • Subscription — receive updates

8. GraphQL Testing with Playwright

Playwright can send GraphQL requests just like other HTTP requests.

typescript
const response = await request.post('/graphql', {

  data: {

    query: `
      query Product($id: ID!) {
        product(id: $id) {
          id
          name
          price
        }
      }
    `,

    variables: {
      id: 100
    }

  }

});

const body = await response.json();

expect(body.data.product.id).toBe(100);

One important GraphQL testing concept is that HTTP 200 does not automatically mean the GraphQL operation succeeded. You might receive:

json
{
  "data": {
    "product": null
  },
  "errors": [
    {
      "message": "Product not found"
    }
  ]
}

Therefore validate both the HTTP status and the errors field when success is expected:

typescript
expect(response.status()).toBe(200);
expect(body.errors).toBeUndefined();

GraphQL testing should cover:

  • Queries
  • Mutations
  • Variables
  • Required arguments
  • Nested objects
  • Schema
  • Invalid fields
  • Error objects
  • Authentication
  • Field-level authorization
  • Null handling
  • Subscriptions when supported

9. What Is WebSocket?

Traditional REST communication follows a request/response model: the client sends a request, the server responds, and the interaction ends. WebSocket creates a persistent bidirectional connection:

text
Client <====================> Server
          WebSocket

After connection establishment, either side can send messages. This is useful for stock prices, trading applications, chat, live notifications, sports scores, real-time dashboards, and order-status updates.

text
Order status changes
        │
        ▼
Backend
        │
        │ WebSocket
        ▼
Browser

"Order SHIPPED"

No page refresh is required.

10. Testing WebSockets

For Node.js/Playwright-based frameworks, a WebSocket client library can be integrated alongside Playwright.

clients/websocketClient.ts
import WebSocket from 'ws';

const ws = new WebSocket(
  'ws://localhost:3000/ws'
);

ws.on('open', () => {

  ws.send(JSON.stringify({
    type: 'SUBSCRIBE',
    orderId: 100
  }));

});

ws.on('message', data => {

  const event =
    JSON.parse(data.toString());

  console.log(event);

});

Important WebSocket tests include:

  • Connection
  • Authentication
  • Subscription
  • Message sending
  • Message receiving
  • Event payload
  • Event type
  • Ordering
  • Disconnect
  • Reconnect
  • Timeout
  • Invalid messages
  • Unauthorized subscriptions
  • Multiple events
  • High-frequency events

A valuable integration scenario is:

text
REST request
     ↓
Backend changes state
     ↓
WebSocket event
     ↓
Playwright validates event
     ↓
UI updates

11. What Is Messaging?

REST generally involves direct communication: the Order Service calls the Inventory Service directly. But an enterprise system may need many systems to react to one event — for example, when an order is created you may need to update inventory, send an email, update analytics, and notify the warehouse. Calling every service directly creates tighter coupling.

Messaging provides another model:

text
Order Service
     │
     │ OrderCreated
     ▼
Message Broker
     │
     ├── Inventory
     ├── Email
     ├── Analytics
     └── Warehouse

This is commonly asynchronous. Technologies may include Kafka, RabbitMQ, AWS SNS/SQS, and other messaging/event platforms.

12. Broker vs Topic

A broker and a topic are not the same thing. The broker is part of the messaging infrastructure. A topic is a named message stream/channel managed by that infrastructure.

text
Publisher
    │
    ▼
Messaging Infrastructure
    │
    ├── order-created
    ├── payment-completed
    └── product-updated

In Kafka specifically, a broker technically refers to an individual Kafka server. Multiple brokers form a Kafka cluster. A topic is a named stream of records distributed through that cluster.

For learning purposes, remember: Broker = messaging infrastructure/server role. Topic = named message stream/channel.

13. Publisher and Subscriber

The publisher produces an event. For example, the Order Service publishes an OrderCreated event to the order-created topic:

json
{
  "eventType": "OrderCreated",
  "orderId": "ORD-1001",
  "customerId": 200,
  "amount": 299.99
}

Subscribers or consumers react to that event:

text
                order-created
                     │
          ┌──────────┼──────────┐
          ▼          ▼          ▼
      Inventory    Email    Analytics
       Consumer   Consumer    Consumer

Each system can process the same business event independently, depending on the messaging technology and consumer configuration.

14. Testing Kafka Topics and Messaging

A useful integration test is:

text
Playwright
    │
    │ POST /orders
    ▼
Order API
    │
    ▼
Order Service
    │
    │ publishes
    ▼
Kafka
    │
    ▼
order-created Topic
    │
    ▼
Test Consumer
    │
    ▼
Validate Event

The test should find the event associated with its own transaction. For example, an event with eventType OrderCreated and the orderId your test just created.

Validate:

  • Topic
  • Event type
  • Event key
  • Payload
  • Required fields
  • Schema
  • Timestamp
  • Correlation ID
  • Duplicate events
  • Ordering when required
  • Sensitive information
Do not simply consume the next message and assume it belongs to your test. Prefer identifiers such as orderId, eventId, correlationId, or transactionId.

15. Testing the Publisher

Suppose POST /orders triggers the Order Service to publish an OrderCreated event to Kafka. Your test should verify both that the business operation succeeds and that the correct event is published.

Also test negative behavior. For example, when payment fails and order creation fails, you may need to verify — depending on the business design — that an OrderCreated event was not published.

Other important cases include:

  • Duplicate publishing
  • Retry behavior
  • Broker unavailable
  • Invalid payload
  • Serialization errors

16. Testing the Consumer

Now reverse the test. Publish a controlled event:

json
{
  "eventType": "OrderCreated",
  "orderId": "ORD-1001"
}

Then verify that the consumer performs the expected operation:

text
Test Publisher
      │
      ▼
order-created
      │
      ▼
Inventory Consumer
      │
      ▼
Inventory DB

Validate that the message was received, parsed, the business logic executed, the database updated, and the message acknowledged. Also test invalid messages and failure handling:

text
Invalid Message
      ↓
Consumer
      ↓
Processing Failure
      ↓
Retry
      ↓
Retry
      ↓
Dead-Letter Queue

Retry and DLQ behavior are important parts of enterprise messaging testing.

17. Database Testing with Playwright

Playwright itself is not a database library, but a Playwright TypeScript framework can use Node.js database clients. For PostgreSQL:

utils/dbClient.ts
import { Pool } from 'pg';

const pool = new Pool({
  connectionString:
    process.env.DB_CONNECTION_STRING
});

const result = await pool.query(
  `
  SELECT id, status
  FROM orders
  WHERE id = $1
  `,
  [orderId]
);

expect(result.rows[0].status)
  .toBe('CREATED');

Database validation is useful when you need to confirm the full chain: API → Business Logic → Database. For example, POST /products returns 201 Created, and PostgreSQL contains the new product row.

Avoid unnecessary database coupling in every API test. Use DB validation when it provides meaningful backend confidence.

18. Handling Eventual Consistency

Distributed applications do not always update every system immediately. For example: REST Request → Order Created → Kafka Event → Consumer → Database Updated. This might take hundreds of milliseconds or several seconds.

Avoid fixed sleeps like await page.waitForTimeout(5000). A better approach is polling.

utils/waitUtils.ts
const rows = await waitUntil(

  () =>
    dbClient.query(
      `
      SELECT *
      FROM orders
      WHERE id = $1
      `,
      [orderId]
    ),

  rows => rows.length === 1,

  {
    timeoutMs: 10000,
    intervalMs: 250
  }

);

Conceptually: check, not ready, wait, check again, ready, continue. This produces faster and more reliable tests than fixed sleeps.

19. Enterprise Playwright Framework Architecture

Instead of putting every protocol directly inside test files, separate infrastructure from business behavior.

text
tests/
├── ui/
├── api/
│   ├── rest/
│   └── graphql/
├── websocket/
├── messaging/
└── e2e/

clients/
├── restClient.ts
├── graphQLClient.ts
├── websocketClient.ts
└── messageClient.ts

services/
├── productService.ts
├── orderService.ts
└── userService.ts

pages/
└── productPage.ts

fixtures/
└── testFixtures.ts

utils/
├── dbClient.ts
├── schemaValidator.ts
├── eventValidator.ts
└── waitUtils.ts

schemas/
└── product.schema.ts

test-data/
└── products.ts

config/
└── env.ts

The dependency flow becomes:

text
                 Playwright Tests
                        │
             ┌──────────┴──────────┐
             ▼                     ▼
       Page Objects             Services
                                   │
                                   ▼
                                 Clients
                                   │
             ┌─────────┬───────────┼─────────┐
             ▼         ▼           ▼         ▼
           REST     GraphQL    WebSocket   Messaging
                                   │
                                   ▼
                               Database

20. Why Use a Client Layer?

Low-level communication belongs in clients. For example:

typescript
await restClient.get('/products/100');

await graphQLClient.execute(
  query,
  variables
);

await messageClient.publish(
  'order-created',
  event
);

await websocketClient.connect();

Tests should not repeatedly implement connection, headers, serialization, error handling, or protocol configuration.

21. Why Use a Service Layer?

The service layer represents business operations. Instead of raw requests in every test, tests can use readable business calls:

typescript
await productService.createProduct(product);

await productService
  .getProductGraphQL(productId);

await orderService.createOrder(
  productId,
  2
);

This creates readable tests where the flow is Test → Business Service → Protocol Client → Application. The service layer hides transport details from business-level tests.

22. Schema Validation

Checking individual values is useful, but API contracts should also be validated:

typescript
validateSchema(
  productSchema,
  product
);

A schema might require: id → number, name → string, price → number, inventory → number. Schema validation helps detect contract-breaking changes that simple assertions may miss.

23. Playwright Fixtures

Playwright fixtures can provide reusable framework components.

tests/api/create-product.spec.ts
test(
  'create product',
  async ({
    productService,
    dbClient
  }) => {

    const product =
      await productService.createProduct({
        name: 'Laptop',
        price: 1499
      });

    expect(product.id).toBeTruthy();

  }
);

The fixture layer can initialize and clean up the REST client, GraphQL client, product service, order service, database client, and authentication. This keeps setup and teardown out of individual tests.

24. The Most Valuable Test: Cross-System E2E

Now combine everything. Imagine this business flow:

text
Playwright
    │
    │ POST /orders
    ▼
REST API
    │
    ▼
Order Service
    │
    ├──────────────► PostgreSQL
    │
    └──────────────► Kafka
                         │
                         ▼
                    OrderCreated
                         │
                         ▼
                  Inventory Service

Order status changes
        │
        ▼
   Order Service
        │
        ▼
    WebSocket
        │
        ▼
       UI

The test can validate:

  1. REST request succeeds
  2. Order is stored in PostgreSQL
  3. Correct Kafka event is published
  4. Consumer processes the event
  5. Order status changes
  6. WebSocket publishes the update
  7. UI displays the new state

That is significantly stronger than checking expect(response.status()).toBe(201).

25. Example Enterprise Playwright Test

Conceptually:

tests/e2e/order-workflow.spec.ts
test(
  'order workflow across REST, DB, Kafka and WebSocket',
  async ({
    orderService,
    dbClient
  }) => {

    // REST
    const order =
      await orderService.createOrder(
        101,
        1
      );

    expect(order.id).toBeTruthy();


    // DATABASE
    const rows =
      await waitUntil(

        () =>
          dbClient.query(
            `
            SELECT id, status
            FROM orders
            WHERE id = $1
            `,
            [order.id]
          ),

        rows =>
          rows.length === 1

      );

    expect(rows[0].status)
      .toBe('CREATED');


    // KAFKA
    const event =
      await messageClient.waitForMessage(
        event =>
          event.eventType ===
            'OrderCreated'
          &&
          event.orderId === order.id
      );

    expect(event.orderId)
      .toBe(order.id);


    // WEBSOCKET
    websocketClient.send({
      type: 'SUBSCRIBE',
      orderId: order.id
    });


    // REST
    await orderService.updateStatus(
      order.id,
      'SHIPPED'
    );


    // WEBSOCKET VALIDATION
    const wsEvent =
      await websocketClient.waitForMessage(
        event =>
          event.eventType ===
            'ORDER_UPDATED'
          &&
          event.orderId === order.id
      );

    expect(wsEvent.status)
      .toBe('SHIPPED');

  }
);

The important idea is not that every test should validate every layer. Instead, create the appropriate test at the appropriate level.

26. Recommended Test Strategy

A healthy enterprise Playwright project might contain:

  • UI Tests — Browser behavior
  • REST Tests — REST contracts and business APIs
  • GraphQL Tests — Queries, mutations and GraphQL contracts
  • WebSocket Tests — Real-time communication
  • Messaging Tests — Producers, consumers and events
  • Database Tests — Persistence and backend state
  • E2E Tests — Critical cross-system business journeys
Do not turn every test into a giant E2E test. Use focused tests for most validation and reserve cross-system tests for important business workflows.

27. Synchronous vs Asynchronous Testing

This distinction is critical. REST and many GraphQL operations are commonly synchronous: Request → Processing → Response. Messaging is commonly asynchronous: Publish → Topic → Consumer → Processing happens later. WebSocket is long-lived and event-driven.

Your automation strategy must reflect these differences. This is why utilities such as waitForMessage(), waitForEvent(), waitUntil(), and pollDatabase() are more appropriate than fixed sleeps.

28. What Should a Professional SDET Remember?

The simplest mental model is:

  • Backend = Server-side logic
  • Microservice = Independently deployable backend capability
  • API = Interface between software systems
  • REST = Resource-oriented API architectural style
  • HTTP = Communication protocol commonly used by web APIs
  • GraphQL = Query language and runtime for APIs
  • WebSocket = Persistent bidirectional communication
  • Messaging = Asynchronous/event-based system communication
  • Broker = Messaging infrastructure/server role
  • Topic = Named message stream/channel
  • Publisher = Produces messages/events
  • Subscriber / Consumer = Receives and processes messages/events

And from the Playwright testing perspective, Playwright can cover browser testing, REST API testing, GraphQL testing, WebSocket integration, database integration, Kafka/messaging integration, and enterprise E2E testing — all in one project.

29. Final Architecture

The complete picture is:

text
                         PLAYWRIGHT
                             │
               Test / Fixture / Service Layer
                             │
        ┌────────────────────┼────────────────────┐
        ▼                    ▼                    ▼
       UI                  REST                GraphQL
        │                    │                    │
        └────────────────────┼────────────────────┘
                             ▼
                         Backend
                             │
               ┌─────────────┼─────────────┐
               ▼             ▼             ▼
            Product        Order          User
            Service       Service        Service
               │             │             │
               ▼             ▼             ▼
                         Databases
                             │
                             ▼
                     Messaging System
                             │
                         Kafka Topics
                             │
                  ┌──────────┼──────────┐
                  ▼          ▼          ▼
               Consumer   Consumer   Consumer
                             │
                             ▼
                         WebSocket
                             │
                             ▼
                         Real-Time UI

Modern Quality Engineering is therefore not simply open browser, click button, check text — and backend automation is not simply call API, check 200. A mature Playwright automation architecture can validate the behavior of a distributed application across the boundaries that matter: UI + REST + GraphQL + Microservices + Database + Kafka/Messaging + WebSocket + End-to-End Business Workflows.

The goal is not to test every technology in every scenario. The goal is to use the correct test level for each risk and then use a smaller number of cross-system Playwright tests to prove that the most important enterprise business workflows work correctly from beginning to end.

Playwright Framework Series

View all →
  1. 1Getting Started with Playwright: Installation, Setup, and Your First Test
  2. 2Playwright Locators: The Complete Guide with Real-World Examples
  3. 3Playwright Actions: Complete Guide to Click, Fill, Hover, Keyboard, Mouse & File Upload
  4. 4Playwright Assertions: The Complete Guide with Real-World Examples
  5. 5Playwright Auto Waiting: The Complete Guide with Real-World Examples
  6. 6Playwright Fixtures: The Complete Guide with Real-World Examples
  7. 7Playwright Browser Context & Multiple Tabs: The Complete Guide with Real-World Examples
  8. 8Playwright Authentication & Session Management: Complete Guide with Enterprise Examples
  9. 9Playwright Network Interception & API Mocking: Complete Guide with Real-World Examples
  10. 10Playwright Page Object Model (POM): The Complete Guide with Enterprise Examples
  11. 11Page Object Model with Playwright: A Practical Guide
  12. 12How to Build a Robust Professional Playwright Framework from Scratch (Step-by-Step)
  13. 13Building an Enterprise Playwright Framework from Scratch

API Testing Series

View all →
  1. 1Playwright API Testing: The Complete Guide with Real-World Examples
  2. 2Part 1 : Playwright API Testing Tutorial: Build Enterprise-Level API Automation Framework
  3. 3Part 2: Playwright API Testing Tutorial: Setting Up Project & Sending Your First API Request
  4. 4Part 3: Mastering CRUD Operations in Playwright API Testing
  5. 5Part 4: Authentication in Playwright API Testing (Bearer Token, JWT, API Key & Reusable Fixtures)
  6. 6Part 5: Building an Enterprise-Level Playwright API Automation Framework
  7. 7Part 6: API Models, Schema Validation & Test Data Management in Playwright
  8. 8Part 7: Custom Fixtures, Hooks, Logging & Parallel Execution in Playwright API Testing
  9. 9Part 8: Building a Production-Ready Playwright API Framework (Environment Management, CI/CD, Reporting & Best Practices)
  10. 10Part 9: Advanced Playwright API Testing Techniques for Enterprise Automation
  11. 11Part 10: Building a Complete Enterprise Playwright API Automation Framework (Final Part)
  12. 12API Testing with Playwright: Request Context, Auth, and Assertions
  13. 13Playwright Backend Testing Tutorial – REST API, GraphQL, WebSocket, Kafka, Database & Microservices

Recommended Next Articles