Analizador de respuestas Json para Array u Object

Estoy escribiendo una biblioteca para consumir una API Json y estoy enfrentando un problema de diseño cuando uso Gson como la biblioteca de análisis.

Uno de los puntos finales devuelve unarray de objetos si todo sale bien así:

[
  { 
   "name": "John",
   "age" : 21
  },
  { 
   "name": "Sarah",
   "age" : 32
  },
]

Sin embargo, el esquema de error para todos los puntos finales en la API es un jsonobject en lugar de una matriz.

{
  "errors": [
     { 
       "code": 1001,
       "message": "Something blew up"
     }
  ]
}

El problema surge cuando se modela esto en POJO. Debido a que el esquema de error es común para todos los puntos finales de la API, decidí tener un resumenApiResponse clase que solo asignará el atributo de errores

public abstract class ApiResponse{

  @SerializedName("errors")
  List<ApiResponseError> errors;
}

public class ApiResponseError {

  @SerializedName("code")
  public Integer code;

  @SerializedName("message")
  public String message;
} 

Ahora me gustaría heredar deApiResponse tener el mapeo de errores "gratis" y una respuesta POJO por punto final de API. Sin embargo, el objeto json de nivel superior para esta respuesta es una matriz (si el servidor logra ejecutar la solicitud), por lo que no puedo crear una nueva clase para asignarla como me gustaría.

Decidí seguir creando una clase extendidaApiResponse:

public class ApiResponsePerson extends ApiResponse {

  List<Person> persons;
}

E implementó un deserializador personalizado para analizar correctamente el json según el tipo de objeto de nivel superior y establecerlo en el campo correcto en la siguiente clase:

public class DeserializerApiResponsePerson implements JsonDeserializer<ApiResponsePerson> {

  @Override 
  public ApiResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

    ApiResponsePerson response = new ApiResponsePerson();
    if (json.isJsonArray()) {
      Type personType = new TypeToken<List<Person>>() {}.getType();
      response.persons = context.deserialize(json, personType);
      return response;
    }
    if (json.isJsonObject()) {
      JsonElement errorJson = json.getAsJsonObject().get("errors");
      Type errorsType = new TypeToken<List<ApiResponseError>>() {}.getType();
      response.errors = context.deserialize(errorJson, errorsType);
      return response;
    }
    throw new JsonParseException("Unexpected Json for 'ApiResponse'");
  }
}

Que luego agregaré al Gson

Gson gson = new GsonBuilder()
    .registerTypeAdapter(ApiResponsePerson.class, new DeserializerApiResponsePerson())
    .create();

¿Hay alguna forma de modelar estos POJO y hacer que Gson reconozca esta estructura sin tener que manejar manualmente este escenario? ¿Hay alguna forma mejor de lograr esto? ¿Me estoy perdiendo algún escenario en el que el deserializador podría fallar o no funcionar como se esperaba?

Gracias

Respuestas a la pregunta(3)

Su respuesta a la pregunta