Using Generic Types in Java to create a method that will handle any API call
package com.dev1.api; | |
import com.dev1.api.exception.ApiException; | |
import com.dev1.api.exception.ApiExceptionNetwork; | |
import com.dev1.api.exception.ApiExceptionUncaught; | |
import com.dev1.api.exception.mapper.ErrorMessage; | |
import com.google.common.collect.ImmutableList; | |
import org.apache.http.HttpHeaders; | |
import org.apache.log4j.Logger; | |
import javax.ws.rs.client.Client; | |
import javax.ws.rs.client.ClientBuilder; | |
import javax.ws.rs.client.Entity; | |
import javax.ws.rs.client.WebTarget; | |
import javax.ws.rs.core.GenericType; | |
import javax.ws.rs.core.MediaType; | |
import javax.ws.rs.core.Response; | |
import java.util.List; | |
import java.util.Map; | |
import static com.dev1.Constants.AUTHENTICATION_SCHEME; | |
public class ApiService<T> { | |
private static final Logger logger = Logger.getLogger(ApiService.class); | |
private final GenericType<T> returnType; | |
public ApiService(GenericType<T> returnType) { | |
this.returnType = returnType; | |
} | |
public T makePost(String apiPath, String apiMethodPath, String token, Object entity) throws ApiException { | |
Response response; | |
try { | |
Client client = ClientBuilder.newClient(); | |
response = client | |
.target(apiPath) | |
.path(apiMethodPath) | |
.request() | |
.header(HttpHeaders.AUTHORIZATION, AUTHENTICATION_SCHEME + " " + token) | |
.post(Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE)); | |
} catch (Exception t) { | |
ApiExceptionNetwork apiException = new ApiExceptionNetwork(t, apiPath + "/" + apiMethodPath); | |
logger.error(apiException); | |
throw apiException; | |
} | |
String jsonReceived = null; | |
try { | |
response.bufferEntity(); | |
List<Integer> successStatuses = ImmutableList.of(Response.Status.OK.getStatusCode(), Response.Status.ACCEPTED.getStatusCode()); | |
if (successStatuses.contains(response.getStatus())) { | |
return response.readEntity(returnType); | |
} else { | |
logApiError(apiPath, apiMethodPath, response); | |
ErrorMessage errorMessage = response.readEntity(ErrorMessage.class); | |
jsonReceived = response.readEntity(String.class); | |
throw new ApiException(errorMessage); | |
} | |
} catch (ApiException e) { | |
throw e; | |
} catch (Exception t) { | |
ApiException apiException = new ApiExceptionUncaught(t, response.getStatus(), apiPath + "/" + apiMethodPath, jsonReceived); | |
logger.error("API returned : " + response.getStatus() + " with URL " + apiPath + "/" + apiMethodPath, apiException); | |
throw apiException; | |
} | |
} | |
/** | |
* On log toute erreur qui ne serait pas du type 401 (comportement normal si erreur d'authentification) | |
*/ | |
private void logApiError(String apiPath, String apiMethodPath, Response response) { | |
List<Integer> badAuthenthStatuses = ImmutableList.of(Response.Status.FORBIDDEN.getStatusCode(), Response.Status.UNAUTHORIZED.getStatusCode()); | |
if (badAuthenthStatuses.contains(response.getStatus())) { | |
logger.error("API returned : " + response.getStatus() + " with URL " + apiPath + "/" + apiMethodPath); | |
} | |
} | |
public T makeGet(String apiPath, String apiMethodPath, String token) throws ApiException { | |
return makeGet(apiPath, apiMethodPath, token, null); | |
} | |
public T makeGet(String apiPath, String apiMethodPath, String token, Map<String, Object> queryParams) throws ApiException { | |
Response response; | |
try { | |
Client client = ClientBuilder.newClient(); | |
WebTarget webTarget = client | |
.target(apiPath) | |
.path(apiMethodPath); | |
if (queryParams != null) { | |
for (Map.Entry<String, Object> entry : queryParams.entrySet()) { | |
webTarget = webTarget.queryParam(entry.getKey(), entry.getValue()); // webtarget is immutable | |
} | |
} | |
response = webTarget | |
.request() | |
.header(HttpHeaders.AUTHORIZATION, AUTHENTICATION_SCHEME + " " + token) | |
.get(); | |
} catch (Exception t) { | |
ApiExceptionNetwork apiException = new ApiExceptionNetwork(t, apiPath + "/" + apiMethodPath); | |
logger.error(apiException); | |
throw apiException; | |
} | |
String jsonReceived = null; | |
try { | |
response.bufferEntity(); | |
List<Integer> successStatuses = ImmutableList.of(Response.Status.OK.getStatusCode(), Response.Status.ACCEPTED.getStatusCode()); | |
if (successStatuses.contains(response.getStatus())) { | |
return response.readEntity(returnType); | |
} else { | |
logApiError(apiPath, apiMethodPath, response); | |
ErrorMessage errorMessage = response.readEntity(ErrorMessage.class); | |
jsonReceived = response.readEntity(String.class); | |
throw new ApiException(errorMessage); | |
} | |
} catch (ApiException e) { | |
throw e; | |
} catch (Exception t) { | |
ApiException apiException = new ApiExceptionUncaught(t, response.getStatus(), apiPath + "/" + apiMethodPath, jsonReceived); | |
logger.error(apiException); | |
throw apiException; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment