All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kiwiproject.jaxrs.KiwiStandardResponses Maven / Gradle / Ivy

Go to download

Kiwi is a utility library. We really like Google's Guava, and also use Apache Commons. But if they don't have something we need, and we think it is useful, this is where we put it.

There is a newer version: 4.5.2
Show newest version
package org.kiwiproject.jaxrs;

import static java.util.Objects.nonNull;
import static org.kiwiproject.base.KiwiStrings.f;

import lombok.experimental.UtilityClass;
import org.kiwiproject.jaxrs.exception.ErrorMessage;
import org.kiwiproject.jaxrs.exception.JaxrsException;
import org.kiwiproject.jaxrs.exception.JaxrsExceptionMapper;

import javax.annotation.Nullable;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.Optional;

/**
 * A set of "standard" JAX-RS responses for various HTTP methods. The "standard" is simply Kiwi's view of
 * what should be in responses for common HTTP methods in a REST-based interface using JSON as the primary
 * data format.
 * 

* One specific thing to note is that the content type is always set to {@link MediaType#APPLICATION_JSON}, since * the primary use case of this class assumes JSON-based REST interfaces. You can change the content type by * using the methods that return a response builder and call one of the {@code type()} methods with a * {@link MediaType} or String argument. This will let you override the default JSON content type in situations * where you need to return a different content type. * * @apiNote Some methods in this class accept {@link Optional} arguments, which we know is considered a code smell * by various people and analysis tools such as IntelliJ's inspections, Sonar, etc. However, we also like to return * {@link Optional} from data access code (e.g. a DAO "findById" method where the object might not exist if it was * recently deleted). In such cases, we can simply take the Optional returned by those finder methods and pass them * directly to the utilities provided here without needing to call additional methods, for example without needing to * call {@code orElse(null)}. So, we acknowledge that it is generally not good to accept {@link Optional} arguments * but we're trading off convenience in this class against "generally accepted" practice. */ @SuppressWarnings("OptionalUsedAsFieldOrParameterType") @UtilityClass public class KiwiStandardResponses { /** * Returns a 200 OK response if the entity is non-null. Otherwise, returns a 404 Not Found response with * a message stating that the entity having type "entityType" was not found using the given identifier field * and value. * * @param identifierField the field which identifies the entity being looked up, e.g. "id" * @param identifier the value of the identifier field, e.g. 42 the value of the identifier field, e.g. 42 * @param entity the entity or null * @param entityType the entity type * @param the entity type * @return a 200 or 404 response with {@code application/json} content type */ public static Response standardGetResponse(String identifierField, Object identifier, @Nullable T entity, Class entityType) { if (nonNull(entity)) { return Response.ok(entity).type(MediaType.APPLICATION_JSON).build(); } var message = f("{} with {} {} not found", entityType.getSimpleName(), identifierField, identifier); return standardNotFoundResponse(message); } /** * Returns a 200 OK response if the entity contains a value. Otherwise, returns a 404 Not Found response with * a message stating that the entity having type "entityType" was not found using the given identifier field * and value. * * @param identifierField the field which identifies the entity being looked up, e.g. "id" * @param identifier the value of the identifier field, e.g. 42 * @param entity an Optional that may or may not contain an entity * @param entityType the entity type * @param the entity type * @return a 200 or 404 response with {@code application/json} content type */ public static Response standardGetResponse(String identifierField, Object identifier, Optional entity, Class entityType) { return standardGetResponse(identifierField, identifier, entity.orElse(null), entityType); } /** * Returns a 200 OK response if the entity is non-null. Otherwise, returns a 404 Not Found response with * a message stating that the entity was not found using the given identifier field and value. * * @param identifierField the field which identifies the entity being looked up, e.g. "id" * @param identifier the value of the identifier field, e.g. 42 * @param entity the entity or null * @param the entity type * @return a 200 or 404 response with {@code application/json} content type */ public static Response standardGetResponse(String identifierField, Object identifier, @Nullable T entity) { if (nonNull(entity)) { return Response.ok(entity).type(MediaType.APPLICATION_JSON).build(); } var message = f("Object with {} {} not found", identifierField, identifier); return standardNotFoundResponse(message); } /** * Returns a 200 OK response if the entity contains a value. Otherwise, returns a 404 Not Found response with * a message stating that the entity was not found using the given identifier field and value. * * @param identifierField the field which identifies the entity being looked up, e.g. "id" * @param identifier the value of the identifier field, e.g. 42 * @param entity an Optional that may or may not contain an entity * @param the entity type * @return a 200 or 404 response with {@code application/json} content type */ public static Response standardGetResponse(String identifierField, Object identifier, Optional entity) { return standardGetResponse(identifierField, identifier, entity.orElse(null)); } /** * Returns a 200 OK response if the entity is non-null. Otherwise, returns a 404 Not Found response with * the given detail message. * * @param entity the entity or null * @param notFoundMessage the specific message to use in the 404 response (if entity is null) * @param the entity type * @return a 200 or 404 response with {@code application/json} content type */ public static Response standardGetResponse(@Nullable T entity, String notFoundMessage) { if (nonNull(entity)) { return Response.ok(entity).type(MediaType.APPLICATION_JSON).build(); } return standardNotFoundResponse(notFoundMessage); } /** * Returns a 200 OK response if the entity contains a value. Otherwise, returns a 404 Not Found response with * the given detail message. * * @param entity an Optional that may or may not contain an entity * @param notFoundMessage the specific message to use in the 404 response (if entity Optional is empty) * @param the entity type * @return a 200 or 404 response with {@code application/json} content type */ public static Response standardGetResponse(Optional entity, String notFoundMessage) { return standardGetResponse(entity.orElse(null), notFoundMessage); } /** * Returns a 201 Created response having the specified Location header and response entity. * * @param location the value for the Location header * @param entity the new entity * @return a 201 response with {@code application/json} content type */ public static Response standardPostResponse(URI location, Object entity) { return standardPostResponseBuilder(location, entity).build(); } /** * Returns a 201 Created response builder having the specified Location header and response entity. * * @param location the value for the Location header * @param entity the new entity * @return a 201 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardPostResponseBuilder(URI location, Object entity) { return KiwiResources.createdResponseBuilder(location, entity).type(MediaType.APPLICATION_JSON); } /** * Returns a 200 OK response having the specified response entity. * * @param entity the updated entity * @return a 200 response with {@code application/json} content type */ public static Response standardPutResponse(Object entity) { return standardPutResponseBuilder(entity).build(); } /** * Returns a 200 OK response builder having the specified response entity. * * @param entity the updated entity * @return a 200 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardPutResponseBuilder(Object entity) { return KiwiResources.okResponseBuilder(entity).type(MediaType.APPLICATION_JSON); } /** * Returns a 200 OK response having the specified response entity. * * @param entity the updated/patched entity * @return a 200 response with {@code application/json} content type */ public static Response standardPatchResponse(Object entity) { return standardPatchResponseBuilder(entity).build(); } /** * Returns a 200 OK response builder having the specified response entity. * * @param entity the updated/patched entity * @return a 200 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardPatchResponseBuilder(Object entity) { return standardPutResponseBuilder(entity); } /** * Returns a 204 No Content response for DELETE requests that do not return an entity. * * @return a 204 response with {@code application/json} content type */ public static Response standardDeleteResponse() { return standardDeleteResponseBuilder().build(); } /** * Returns a 204 No Content response builder for DELETE requests that do not return an entity. * * @return a 204 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardDeleteResponseBuilder() { return Response.noContent().type(MediaType.APPLICATION_JSON); } /** * Returns a 200 OK response for DELETE requests that return an entity. * * @param deletedEntity the deleted entity * @return a 200 response with {@code application/json} content type */ public static Response standardDeleteResponse(Object deletedEntity) { return standardDeleteResponseBuilder(deletedEntity).build(); } /** * Returns a 200 OK response builder for DELETE requests that return an entity. * * @param deletedEntity the deleted entity * @return a 200 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardDeleteResponseBuilder(Object deletedEntity) { return Response.ok(deletedEntity).type(MediaType.APPLICATION_JSON); } /** * Returns a 400 Bad Request response containing an {@link ErrorMessage} entity which uses {@code errorDetails} * as the detailed error message. * * @param errorDetails the error message to use * @return a 400 response with {@code application/json} content type */ public static Response standardBadRequestResponse(String errorDetails) { return standardBadRequestResponseBuilder(errorDetails).build(); } /** * Returns a 400 Bad Request response builder containing an {@link ErrorMessage} entity which uses * {@code errorDetails} as the detailed error message. * * @param errorDetails the error message to use * @return a 400 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardBadRequestResponseBuilder(String errorDetails) { return standardErrorResponseBuilder(Response.Status.BAD_REQUEST, errorDetails); } /** * Returns a 401 Unauthorized response containing an {@link ErrorMessage} entity which uses {@code errorDetails} * as the detailed error message. * * @param errorDetails the error message to use * @return a 401 response with {@code application/json} content type */ public static Response standardUnauthorizedResponse(String errorDetails) { return standardUnauthorizedResponseBuilder(errorDetails).build(); } /** * Returns a 401 Unauthorized response builder containing an {@link ErrorMessage} entity which uses * {@code errorDetails} as the detailed error message. * * @param errorDetails the error message to use * @return a 401 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardUnauthorizedResponseBuilder(String errorDetails) { return standardErrorResponseBuilder(Response.Status.UNAUTHORIZED, errorDetails); } /** * Returns a 404 Not Found response containing an {@link ErrorMessage} entity which uses {@code errorDetails} * as the detailed error message. * * @param errorDetails the error message to use * @return a 404 response with {@code application/json} content type */ public static Response standardNotFoundResponse(String errorDetails) { return standardNotFoundResponseBuilder(errorDetails).build(); } /** * Returns a 404 Not Found response builder containing an {@link ErrorMessage} entity which uses * {@code errorDetails} as the detailed error message. * * @param errorDetails the error message to use * @return a 404 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardNotFoundResponseBuilder(String errorDetails) { return standardErrorResponseBuilder(Response.Status.NOT_FOUND, errorDetails); } /** * Returns a response having the given status and an {@link ErrorMessage} entity which uses {@code errorDetails} * as the detailed error message. *

* Does not verify that the given status is actually an error status. * * @param status the error status to use * @param errorDetails the error message to use * @return a response with the given status code and {@code application/json} content type */ public static Response standardErrorResponse(Response.Status status, String errorDetails) { return standardErrorResponseBuilder(status, errorDetails).build(); } /** * Returns a response builder having the given status and an {@link ErrorMessage} entity which uses * {@code errorDetails} as the detailed error message. *

* Does not verify that the given status is actually an error status. * * @param status the error status to use * @param errorDetails the error message to use * @return a response builder with the given status code and {@code application/json} content type */ public static Response.ResponseBuilder standardErrorResponseBuilder(Response.Status status, String errorDetails) { return JaxrsExceptionMapper.buildResponseBuilder(new JaxrsException(errorDetails, status.getStatusCode())); } /** * Returns a 202 Accepted response having the specified response entity. *

* This generally applies to POST, PUT, and PATCH requests that might take a while and are processed asynchronously. * * @param entity the accepted entity * @return a 202 response with {@code application/json} content type */ public static Response standardAcceptedResponse(Object entity) { return standardAcceptedResponseBuilder(entity).build(); } /** * Returns a 202 Accepted response builder having the specified response entity. *

* This generally applies to POST, PUT, and PATCH requests that might take a while and are processed asynchronously. * * @param entity the accepted entity * @return a 202 response builder with {@code application/json} content type */ public static Response.ResponseBuilder standardAcceptedResponseBuilder(Object entity) { return Response.accepted(entity).type(MediaType.APPLICATION_JSON); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy