/**
* ElementType.METHOD = Can put on individual methods
* ElementType.TYPE = Can put on entire class
* RetentionPolicy.RUNTIME = annotation is available at runtime
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface StdResponseBody{}
@EqualsAndHashCode
@Data
@NoArgsConstructor
public class StandardResponse<T> {
private boolean success;
private T data;
private ErrorResponse error;
// success without data
public static <T> StandardResponse<T> success() {
StandardResponse<T> response = new StandardResponse<>();
response.setSuccess(true);
response.setData(null);
return response;
}
// success with data
public static <T> StandardResponse<T> success(T data) {
StandardResponse<T> response = new StandardResponse<>();
response.setSuccess(true);
response.setData(data);
return response;
}
// error response
public static <T> StandardResponse<T> error(ErrorResponse error) {
StandardResponse<T> response = new StandardResponse<>();
response.setSuccess(false);
response.setError(error);
return response;
}
}
Example of a successful response:
// with data
{
"success": true,
"data": {
"id": 1,
"name": "Alice"
},
"error": null
}
// without data
{
"success": true,
"data": null,
"error": null
}
Example of an error response:
{
"success": false,
"data": null,
"error": {
"code": "USER_404",
"message": "User not found",
"timestamp": "2026-01-25T10:00:00"
}
}