Service Design Tips and Best Practices for Robust API Development
This article explores essential service design considerations beyond standard guidelines, covering API path structuring, request handling, parameter design, security measures, monitoring, degradation strategies, and code examples to help build flexible, secure, and maintainable backend services.
In today’s rapidly evolving technical landscape, service design goes beyond following generic design standards; it must also ensure flexibility for future changes and meet user expectations.
The article discusses key factors to consider when designing services, aiming to make APIs easy to integrate, understand, and extend.
System Overview
JD Enterprise VOP (Intelligent Procurement) provides hundreds of standard API services to thousands of customers, enabling them to build self‑procurement malls.
Service Design Tips
Use a unified first‑level path (e.g., domain/api/ ) to centralize API requests, simplifying security controls such as authentication, authorization, logging, rate limiting, and monitoring.
Organize subsequent paths by business domain (e.g., order/api/order , product/api/product ) so callers can easily identify the module.
Consider service granularity: decide whether to expose a separate price service or embed price data within product details, and whether order logistics should be part of the order detail service, balancing completeness with flexibility.
Service Request Methods
Most services should support AJAX requests with a fixed data format (JSON/XML) for easy extension, while special cases like checkout or login may require non‑AJAX handling with server‑side redirects.
Input/Output Parameters
Design parameters with extensibility in mind to avoid breaking existing clients; use Long or String for numeric fields that may grow.
Distinguish between “unset” and zero values by using wrapper types.
Expose only necessary response fields; mask or encrypt sensitive data such as addresses and phone numbers.
Provide clear field definitions, length limits, ranges, consistent naming, format specifications, and enum explanations.
When adding new fields to published services, consider strict deserialization modes; add optional extension fields to avoid breaking existing clients.
Business Logic Recommendations
Support batch processing to reduce high‑concurrency calls.
Implement horizontal permission checks to prevent callers from accessing data outside their scope.
Use dedicated thread pools for critical business logic to avoid resource contention.
Exception Handling
Define clear error codes for write operations so callers can automate retry, alert, or ignore decisions.
Wrap unknown exceptions in a unified response format using interceptors.
Service Dependencies
Classify external dependencies as strong or weak; strong dependencies trigger short‑circuit failures, while weak dependencies can be ignored with alerts to maintain overall availability.
Monitoring and Logging
Record request/response logs for all services, especially those handling finance, orders, and payments, to support risk assessment and business analytics.
Collect call metrics to detect abnormal usage patterns and enforce rate limiting or security controls.
Degradation Strategies
Identify critical and non‑critical modules; embed degradation logic in non‑critical code to preserve core service availability during failures.
Handling Obsolete Services
Route compatible old services to new implementations.
Deprecate by intercepting calls and returning standardized error codes, allowing graceful migration.
Security Measures
Never trust third‑party services or callers; enforce strict input validation, rate limiting, and fine‑grained permission controls.
Sensitive Field Protection
Encrypt sensitive fields (e.g., phone numbers, addresses) at transport, application, or database layers using industry‑standard algorithms.
Interface Tamper‑Proofing
Enforce HTTPS for all data transmission.
Use digital signatures or MACs to verify data integrity.
Combine API keys with timestamps to prevent replay attacks.
Request/Response Encryption
Clients may require full encryption of request and response payloads; a platform is provided to load customer‑specific encryption SDKs and apply encryption/decryption transparently via interceptors.
{
"success": true,
"resultMessage": "success",
"resultCode": "0000",
"result": {}
} /**
* @description Specify customer request/response encryption interceptor
*/
@Service
public class EncryptInterceptor extends HandlerInterceptorAdapter {
// Decrypt before handling
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(!(request instanceof DecryptionRequestWrapper)){
return true;
}
// Retrieve client auth info, determine if encryption is enabled, decrypt parameters, and populate request
return true;
}
// Encrypt after handling
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// Retrieve client identity, check encryption flag, encrypt response data, write back
}
}Conclusion
Building robust services requires adhering to design standards while also addressing security, scalability, extensibility, and degradation capabilities to meet evolving business needs.
JD Retail Technology
Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.