36 Essential Tips for Designing Robust Backend APIs

This comprehensive guide presents 36 practical recommendations for backend engineers, covering parameter validation, compatibility, extensibility, idempotency, error handling, logging, performance optimization, caching, rate limiting, security, transaction management, and clear communication to help design reliable, maintainable, and scalable service interfaces.

ITPUB
ITPUB
ITPUB
36 Essential Tips for Designing Robust Backend APIs

1. Parameter Validation

Validate all input and output parameters to prevent bugs such as inserting oversized strings into a varchar(16) column or returning null where a non‑null value is expected.

For example, if a database column is defined as varchar(16) and a 32‑character string is received, the insert will fail without validation.

2. Compatibility When Modifying Existing APIs

Never break backward compatibility of public APIs; otherwise releases may fail. When adding a new parameter to a Dubbo interface, keep the old method and forward calls with a null placeholder.

// Old interface
void oldService(A, B) {
    // Compatibility: pass null for new parameter C
    newService(A, B, null);
}

// New interface (cannot delete old one yet)
void newService(A, B, C) {
    ...
}

3. Design for Extensibility

Consider future scenarios when defining an API. For a face‑recognition feature, design a generic interface that can be reused across modules (e.g., employee management, payment) by adding new enum values instead of creating separate endpoints.

4. Duplicate Request Handling

Implement de‑duplication for write‑heavy or financial operations. Use Redis or a database unique index (e.g., transaction ID) to filter repeated requests within a short time window.

5. Thread‑Pool Isolation for Critical APIs

Allocate dedicated thread pools for high‑priority services such as login, transfer, or order placement to prevent a single buggy service from exhausting shared resources.

6. Third‑Party Calls: Exception & Timeout Management

Exception handling – decide whether to retry, fail fast, or raise alerts.

Timeouts – set reasonable limits to avoid hanging threads and resource exhaustion.

Retry count – determine the appropriate number of retries based on business impact.

7. Circuit Breaker and Degradation

To avoid service avalanche, use circuit‑breaker patterns (e.g., Hystrix) that disable downstream calls when they become unhealthy.

8. Logging Best Practices

Log entry, parameters, and exceptions for critical operations such as money transfers. Example:

public void transfer(TransferDTO transferDTO) {
    log.info("invoke transfer begin");
    log.info("invoke transfer, parameters:{}", transferDTO);
    try {
        res = transferService.transfer(transferDTO);
    } catch (Exception e) {
        log.error("transfer fail, account:{}", transferDTO.getAccount());
        log.error("transfer fail, exception:{}", e);
    }
    log.info("invoke transfer end");
}

9. Single‑Responsibility for API Functions

Each API should perform a single, well‑defined task (e.g., login returns only authentication result and userId). Group unrelated functionalities into separate services.

10. Asynchronous Processing When Appropriate

Use thread pools or message queues for non‑blocking actions such as sending emails after user registration or handling batch transfers.

11. Parallel Calls to Reduce Latency

When an endpoint aggregates data from multiple sources (user info, banner, popup), issue the calls in parallel (e.g., using CompletableFuture) to cut total response time.

12. Batch Operations Over Loops

Prefer bulk inserts or batch remote calls instead of per‑item loops. Example:

// Bad: per‑item remote call
for (int i = 0; i < n; i++) {
    remoteSingleQuery(param);
}

// Good: batch request
remoteBatchQuery(param);

13. Caching Strategies

Cache read‑heavy, write‑light data (e.g., product info). Use Redis for distributed caching or Guava/Caffeine for local caches, while handling consistency, cache penetration, and avalanche scenarios.

14. Hot‑Data Isolation

Isolate high‑traffic data via business, system, user, or data segregation to prevent spikes from overwhelming a single component.

15. Configurable Parameters (e.g., Red‑Packet Skins)

Store UI variations or thresholds in configuration tables instead of hard‑coding, enabling runtime changes without redeployment.

16. Idempotency Design

Ensure repeated requests produce the same effect. Common techniques include unique keys, token tables, optimistic/pessimistic locks, and distributed locks.

17. Read‑Write Separation

Direct write traffic to the primary database and read‑only queries to replicas, while accounting for replication lag.

18. Pagination for Large Result Sets

Split massive responses into pages or separate APIs to reduce payload size and processing overhead.

19. SQL Optimization

Analyze execution plans with EXPLAIN.

Profile queries using SHOW PROFILE.

Apply proper indexing, covering indexes, and left‑most prefix rules.

Handle large pagination via keyset pagination.

Consider sharding or Elasticsearch for very large tables.

20. Lock Granularity Control

Avoid coarse‑grained locks; lock only the shared resources that truly need protection.

21. Unified Error Codes and Messages

Define clear status codes and descriptive error messages for clients, avoiding exposure of raw stack traces.

22. Robust Exception Handling

Prefer logging over e.printStackTrace().

Log the caught exception details.

Avoid catching generic Exception unless necessary.

Use try‑with‑resources or finally to release resources.

Wrap and rethrow custom exceptions preserving the original cause.

Handle runtime exceptions (e.g., NPE) with pre‑checks.

23. Clean Business Logic

Write clear, well‑commented code and avoid redundant database lookups by passing already‑fetched objects.

24. Large Files, Transactions, and Objects

Stream large files with BufferedReader instead of loading them entirely.

Keep transactions short to avoid deadlocks and replication lag.

Beware of large objects that may trigger Full GC.

25. Rate Limiting

Protect the system from traffic spikes using Guava RateLimiter for single‑node limits or Redis/Sentinel for distributed throttling.

26. Runtime Exception Prevention

Check collection bounds and nulls before accessing elements to avoid IndexOutOfBoundsException or NullPointerException.

27. API Security (Token & Signature)

Implement token‑based authentication stored in Redis with expiration, and use request signing (client private key, server public key) to guarantee integrity.

28. Distributed Transaction Solutions

Two‑Phase Commit (2PC) / Three‑Phase Commit (3PC)

TCC (Try‑Confirm‑Cancel)

Local message tables

Maximum‑effort notification

Seata

29. Common Transaction‑Failure Scenarios

Non‑public or final methods.

Internal method calls bypassing proxies.

Missing Spring management.

Multithreaded access with different connections.

Unsupported storage engines.

Swallowed exceptions in try‑catch.

Incorrect propagation settings.

30. Frequently Used Design Patterns

Apply patterns such as Strategy, Factory, Template Method, and Observer to improve code reuse, readability, and reliability.

31. Linear‑Safety in High Concurrency

Prefer thread‑safe collections like ConcurrentHashMap over non‑safe ones (e.g., HashMap) to avoid infinite loops or data corruption.

32. Clear Naming and Interface Definition

Use expressive names and concise signatures to aid future maintenance and onboarding.

33. API Versioning

Include a version field in request payloads to support backward compatibility and gradual rollout.

34. Code Quality Practices

Eliminate duplicate code.

Group parameters into DTOs.

Keep methods short.

Simplify conditional logic.

Remove dead code and enforce formatting.

Avoid over‑engineering.

35. Ensuring Correctness Under Concurrency

Use optimistic locking (CAS) for balance updates, and distributed locks (e.g., Redis) to prevent overselling in flash‑sale scenarios.

36. Communication with Front‑End and Product Teams

Align API definitions with front‑end expectations early, involve technical leads for tough decisions, and keep product stakeholders informed throughout development.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendScalabilityvalidationSecurityapi-design
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.