Why Your RPC Interfaces Should Avoid HTTP‑Style Responses
This article explains why designing RPC (JSF) interfaces to return HTTP‑like result objects with errorCode, errorMessage, and data defeats the purpose of RPC, and it offers concrete guidelines and Java examples for building clean, exception‑driven RPC APIs.
Introduction
In everyday development, RPC (Remote Procedure Call) plays a crucial role by allowing remote services to be called like local methods, improving system scalability and flexibility. However, many developers design JSF interfaces that return objects resembling HTTP responses, containing errorCode, errorMessage, and data fields, which contradicts the original intent of RPC.
RPC should hide communication complexity so developers can focus on business logic. Proper RPC interface design should mirror local method design: simple return values and exception handling.
1. Misguided RPC Interface Design
1.1 Common Mistake
Developers often copy HTTP response patterns, defining a unified result class:
public class Result<T> {
private int errorCode;
private String errorMessage;
private T data;
// getters and setters
}and a method like: public Result<User> getUserById(int userId); The caller must first check errorCode before extracting data, which adds unnecessary complexity.
1.2 What’s Wrong?
1.2.1 Forgetting the Original Goal
Returning a Result object with errorCode, errorMessage, and data is unnecessary and makes the call more cumbersome. RPC aims to hide network details; adding such a wrapper forces the caller to unpack and check error codes.
1.2.2 Improper Exception Handling
Passing error information via return values instead of throwing exceptions leads to:
Developers forgetting to check errorCode, causing silent failures.
Scattered and inconsistent error handling across methods.
Loss of full stack trace, making debugging harder.
Example of the problem:
Result<User> result = userService.getUserById(userId);
User user = result.getData(); // If errorCode was not checked, user may be null → NullPointerExceptionUsing exceptions forces the caller to handle errors explicitly:
try {
User user = userService.getUserById(userId);
// business logic
} catch (UserNotFoundException e) {
// handle missing user
}1.2.3 Added Redundancy
Every RPC method returning a Result forces repetitive error‑code checks, violates the Single Responsibility Principle, and hinders method chaining or functional composition.
Inconsistent return types: Some methods return Result, others return the actual object, increasing cognitive load.
Hard to compose: Result does not fit well with stream or fluent APIs.
Breaks single‑responsibility: Methods should perform one function, not both return data and convey error codes.
2. Correct JSF Interface Design Principles
Instead of a unified result wrapper, define methods that return the actual business object and declare the possible exceptions:
public interface ProviderQueryService {
/**
* Query provider metrics
* @param statisticDate 统计日期
* @param providerIdList 供应列表
* @return List of provider metrics
*/
List<ProviderRateInfo> queryByDay(Date statisticDate, List<Long> providerIdList)
throws InvalidInputException, SystemRpcException;
}Callers handle errors via try‑catch blocks:
try {
List<ProviderRateInfo> res = providerQueryService.queryByDay(statisticDate, providerIdList);
// process business logic
} catch (InvalidInputException e) {
// handle parameter validation errors
} catch (SystemRpcException e) {
// handle system execution errors
}Benefits of this approach:
Enforced error handling: Exceptions compel callers to address failures.
Clear error propagation: Stack traces pinpoint the source of problems.
Unified handling strategy: Global exception handlers can be applied.
Reduced code redundancy: No repetitive if‑else checks.
Improved readability: Code is cleaner and intent is obvious.
Facilitates method composition: Returns can be used in streams or fluent APIs.
Framework‑level RPC exceptions (e.g., RpcException) are also thrown and can be caught by the client.
Conclusion
Think of code as art: each line should be concise and elegant. Overusing generic wrappers like Result, Response, or ErrorCode clutters the design. Follow the principles of simple return values, proper exception usage, and clear contracts to build robust, maintainable RPC services.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD Cloud Developers
JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.
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.
