Backend Development 8 min read

Proper RPC Interface Design: Avoiding Result Wrappers and Using Exceptions

The article explains why designing RPC interfaces with generic Result objects that contain errorCode, errorMessage and data defeats RPC's purpose, and demonstrates how returning plain business objects and leveraging Java exceptions leads to cleaner, more maintainable backend code.

JD Tech Talk
JD Tech Talk
JD Tech Talk
Proper RPC Interface Design: Avoiding Result Wrappers and Using Exceptions

In daily development, RPC (Remote Procedure Call) is crucial for building scalable systems, but many developers mistakenly design RPC interfaces to return HTTP‑like response objects containing fields such as errorCode , errorMessage and data .

This violates the original purpose of RPC, which is to hide network details and make remote calls look like local method invocations; the proper design should return simple values and use exceptions for error handling.

Common wrong pattern: a generic Result class with errorCode , errorMessage , data and RPC methods returning Result . Callers must check the error code before extracting data, increasing boilerplate and risk of ignored errors.

public class Result
{
private int errorCode;
private String errorMessage;
private T data;
// getters and setters
}

Another example of the flawed method signature:

public Result
getUserById(int userId);

Problems include forgetting to check error codes, scattered error handling, loss of stack traces, and added code redundancy, which contradicts the single‑responsibility principle and make method composition difficult.

Correct approach: design RPC methods like ordinary Java methods, returning the actual business object (e.g., List ) and letting the method throw specific exceptions such as InvalidInputException or SystemRpcException . Example interface and usage are shown.

public interface ProviderQueryService {
/**
* Query provider metrics
* @param statisticDate 统计日期
* @param providerIdList 供应列表
* @return 供应商指标列表
*/
List
queryByDay(Date statisticDate, List
providerIdList)
throws InvalidInputException, SystemRpcException;
}

Usage with exception handling:

try {
List
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 design are mandatory error handling, clear propagation of exceptions with stack traces, unified global error handling, reduced boilerplate, improved readability, and easier method chaining or functional composition.

In summary, RPC interfaces should be as simple as local calls, rely on Java’s exception mechanism, and avoid wrapping results in generic response objects.

backendJavasoftware architectureRPCException HandlingInterface Design
JD Tech Talk
Written by

JD Tech Talk

Official JD Tech public account delivering best practices and technology innovation.

0 followers
Reader feedback

How this landed with the community

login 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.