Skip to content

Chapter 5 of 7

API Architectural Styles and Security

REST is an architectural style organized around resources identified by URIs, with a uniform interface, stateless requests, and representations (typically JSON) transferred over HTTP. Its core constraints—client–server separation, statelessness, cacheability, uniform interface, layered system, and optional code-on-demand—come from Fielding's dissertation. RPC, by contrast, models verbs (actions and procedures) rather than nouns and often uses POST against a custom endpoint with method semantics defined by the API itself. RESTful design tends to map naturally to HTTP verbs; RPC tends to encode business operations as named endpoints. Both have their place, and the choice influences how clients and tests are structured.

GraphQL is a query language and runtime that lets clients send a single POST to one endpoint with a query describing exactly which fields they need, and the server returns a JSON response matching that shape. The flexibility introduces a unique testing concern: because one endpoint can resolve many resources, malicious or naive queries can otherwise exfiltrate data or trigger denial of service. Tests should cover query complexity analysis, depth limits, and field-level authorization. A query depth attack nests fields many layers deep (for example user → friends → friends), causing exponential work; defenses include depth limits and cost analysis. A related backend hazard is the N+1 query problem, where a single response triggers one database query per item due to a loop fetching related rows, hurting performance linearly with result size—fixable with eager loading or batched fetchers.

The OWASP API Security Top 10 tracks the most critical API security risks. Broken Object Level Authorization (BOLA) happens when the server fails to verify that the authenticated user may access a specific object ID—GET /orders/123 returning any user's order is the canonical case. Broken Function Level Authorization is the failure to restrict access to privileged endpoints like /admin based on the caller's role. Excessive Data Exposure occurs when an API returns more fields than the consumer needs because the serializer is overly broad, leaking password hashes or PII. Mass Assignment vulnerabilities let attackers set fields they should not control (for example is_admin=true in a profile update) by binding client-supplied fields directly to a model without filtering. Server-Side Request Forgery (SSRF) tricks the server into fetching an unintended URL—often a cloud metadata endpoint like 169.254.169.254, which can leak IAM credentials. SQL injection remains a threat whenever untrusted input is concatenated into queries; testing with payloads like ' OR 1=1-- helps verify defenses. Other defensive testing practices include parameter pollution tests (duplicate query parameters), fuzz testing (random, malformed, or unexpected inputs), boundary value testing at the edges of valid ranges, and equivalence partitioning to keep the test set small but thorough.

All chapters
  1. 1Foundations of API Testing
  2. 2HTTP Status Codes and Communication
  3. 3HTTP Methods, Headers, and Request Formats
  4. 4Authentication, Authorization, and Browser Concerns
  5. 5API Architectural Styles and Security
  6. 6Contract Testing, Mocks, and Test Patterns
  7. 7Performance, Observability, and Operations

Drill it

Reading is not remembering. These come from the API Testing deck:

Q

What is API testing?

API testing verifies that an application's interfaces behave correctly in terms of functionality, contracts, performance, security, and error handling.

Q

Why is API testing valuable?

It catches issues below the UI layer, runs faster than end-to-end tests, and provides direct confidence in service behavior.

Q

What is the difference between unit, integration, and API tests?

Unit tests isolate small pieces of logic, integration tests verify components working together, and API tests validate behavior at the service boundary.

Q

What is a contract in API testing?

A contract describes the expected structure and behavior of requests and responses, including fields, types, and status codes.