Skip to content

Commit

Permalink
Allow v2 collection to be requested with legacy implementation to sup…
Browse files Browse the repository at this point in the history
…port migrating to that newer version.
  • Loading branch information
arucard21 committed Jun 3, 2022
1 parent 0665860 commit b32b7be
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
import javax.ws.rs.container.ContainerRequestContext;

import simplyrestful.api.framework.queryparams.SortOrder;
import simplyrestful.api.framework.webresource.api.implementation.DefaultCollectionGet;

public class QueryParamUtils {
public static final String QUERY_PARAM_VALUE_DELIMITER = ",";
public static final String HAL_EMBEDDED_OBJECT_NAME = "_embedded";
public static final String HAL_LINKS_OBJECT_NAME = "_links";
public static final String FIELDS_OVERRIDE_REQUEST_CONTEXT_PROPERTY = "simplyrestful.fields.json.override";
public static final String FIELDS_PARAM_NAME = "fields";
public static final String FIELDS_PARAM_SEPARATOR = ",";
public static final String QUERY_PARAM_VALUE_DELIMITER = ",";

/**
* Set the default value for the list of fields as request property as fields override.
Expand All @@ -32,12 +31,12 @@ public static void configureFieldsDefault(ContainerRequestContext requestContext
if (!fieldsQueryParamProvided(requestContext)) {
requestContext.setProperty(
FIELDS_OVERRIDE_REQUEST_CONTEXT_PROPERTY,
String.join(FIELDS_PARAM_SEPARATOR, fieldsDefaults));
String.join(QUERY_PARAM_VALUE_DELIMITER, fieldsDefaults));
}
}

public static boolean fieldsQueryParamProvided(ContainerRequestContext requestContext) {
return requestContext.getUriInfo().getQueryParameters().containsKey(FIELDS_PARAM_NAME);
return requestContext.getUriInfo().getQueryParameters().containsKey(DefaultCollectionGet.QUERY_PARAM_FIELDS);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,22 @@
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import simplyrestful.api.framework.MediaTypeUtils;
import simplyrestful.api.framework.QueryParamUtils;
import simplyrestful.api.framework.api.crud.DefaultCount;
import simplyrestful.api.framework.api.crud.DefaultList;
import simplyrestful.api.framework.hal.HALCollectionV2Builder;
import simplyrestful.api.framework.resources.HALCollection;
import simplyrestful.api.framework.resources.HALCollectionV2;
import simplyrestful.api.framework.resources.HALResource;
Expand All @@ -27,6 +32,8 @@
/**
* Provide a legacy implementation for the deprecated HALCollectionV1 resource.
*
* It defaults to returning a v1 collection but allows requesting a v2 collection.
*
* @deprecated Use {@link DefaultCollectionGet} with the {@link HALCollectionV2} resource instead.
*/
@Deprecated(since = "0.12.0")
Expand All @@ -38,25 +45,44 @@ public interface LegacyCollectionGet<T extends HALResource> extends DefaultList<
public static final String QUERY_PARAM_FIELDS_COMPACT = "_links";

/**
* Retrieve the paginated collection of resources as the deprecated v1 collection.
*
* Retrieve the paginated collection of resources.
* <p>
* Unless stated otherwise, these parameters can only be used with {@link HALCollectionV2}.
* </p>
* @param requestContext is a JAX-RS context object.
* @param resourceInfo is a JAX-RS context object.
* @param uriInfo is a JAX-RS context object.
* @param page is the page number of the paginated collection of resources
* @param pageSize is the size of a single page in this paginated collection of resources
* @param compact determines whether the resource in the collection only shows its self-link (if true), or the entire resource (if false)
* @param httpHeaders is a JAX-RS context object.
* @param page is the page number of the paginated collection of resources (for {@link HALCollectionV1} only)
* @param pageStart is the offset at which the requested page starts.
* @param pageSize is the size of a single page in this paginated collection of resources (for both {@link HALCollectionV1}
* and {@link HALCollectionV2})
* @param compact determines whether the resource in the collection only shows its self-link (if true), or the entire
* resource (if false) (for {@link HALCollectionV1} only). If fields is provided, compact is always considered false.
* @param fields is a list that defines which fields should be retrieved. This is only included for convenience as
* it is already handled by the framework. It can be used to filter on these fields in the backend as well, e.g. to
* improve performance. If both compact and fields are provided, compact is ignored.
* improve performance.
* @param query is a FIQL query that defines how the resources should be filtered.
* @param sort is a list of field names on which the resources should be sorted. This is only included for convenience
* as it is already handled by the framework.
* @return the paginated collection of resources.
*/
@GET
@Produces(HALCollectionV1.MEDIA_TYPE_HAL_JSON)
@Produces({
HALCollectionV2.MEDIA_TYPE_HAL_JSON+";qs=0.2",
HALCollectionV2.MEDIA_TYPE_JSON+";qs=0.4",
HALCollectionV1.MEDIA_TYPE_HAL_JSON+";qs=0.9"
})
@Operation(description = "Get a list of resources")
@ApiResponse(content = {
@Content(
mediaType = HALCollectionV2.MEDIA_TYPE_HAL_JSON,
schema = @Schema(
implementation = HALCollectionV2.class)),
@Content(
mediaType = HALCollectionV2.MEDIA_TYPE_JSON,
schema = @Schema(
implementation = HALCollectionV2.class)),
@Content(
mediaType = HALCollectionV1.MEDIA_TYPE_HAL_JSON,
schema = @Schema(
Expand All @@ -66,12 +92,20 @@ default HALCollection<T> listHALResources(
@Context
ContainerRequestContext requestContext,
@Context
ResourceInfo resourceInfo,
@Context
UriInfo uriInfo,
@Context
HttpHeaders httpHeaders,
@QueryParam(V1_QUERY_PARAM_PAGE)
@DefaultValue(V1_QUERY_PARAM_PAGE_DEFAULT)
@Parameter(description = "The page to be shown", required = false)
int page,
@QueryParam(DefaultCollectionGet.QUERY_PARAM_PAGE_SIZE)
@QueryParam(DefaultCollectionGet.QUERY_PARAM_PAGE_START)
@DefaultValue(DefaultCollectionGet.QUERY_PARAM_PAGE_START_DEFAULT)
@Parameter(description = "The page to be shown", required = false)
int pageStart,
@QueryParam(DefaultCollectionGet.QUERY_PARAM_PAGE_SIZE)
@DefaultValue(DefaultCollectionGet.QUERY_PARAM_PAGE_SIZE_DEFAULT)
@Parameter(description = "The amount of resources shown on each page", required = false)
int pageSize,
Expand All @@ -91,23 +125,47 @@ default HALCollection<T> listHALResources(
@DefaultValue(DefaultCollectionGet.QUERY_PARAM_SORT_DEFAULT)
@Parameter(description = "The fields on which the resources should be sorted", required = false)
List<String> sort) {
if(!QueryParamUtils.fieldsQueryParamProvided(requestContext)) {
fields = compact ? Collections.singletonList(QUERY_PARAM_FIELDS_COMPACT) : Collections.singletonList(DefaultCollectionGet.QUERY_PARAM_FIELDS_ALL);
MediaType selected = MediaTypeUtils.selectMediaType(resourceInfo, httpHeaders);
if(selected.equals(MediaType.valueOf(HALCollectionV2.MEDIA_TYPE_JSON))) {
QueryParamUtils.configureFieldsDefault(requestContext, QueryParamUtils.stripHALStructure(fields));
}
else {
QueryParamUtils.configureFieldsDefault(requestContext, fields);
}
QueryParamUtils.configureFieldsDefault(requestContext, fields);
int calculatedPageStart = (page -1) * pageSize;
return HALCollectionV1Builder.fromPartial(
this.list(
calculatedPageStart,
pageSize,
QueryParamUtils.stripHALStructure(fields),
QueryParamUtils.stripHALStructure(query),
QueryParamUtils.parseSort(sort)),
uriInfo.getRequestUri(),
this.count(QueryParamUtils.stripHALStructure(query)))
.page(page)
.maxPageSize(pageSize)
.compact(compact)
.build();

if(selected.equals(MediaType.valueOf(HALCollectionV1.MEDIA_TYPE_HAL_JSON))) {
int calculatedPageStart = (page -1) * pageSize;
if(uriInfo.getQueryParameters().containsKey(DefaultCollectionGet.QUERY_PARAM_FIELDS)) {
compact = false;
}
else {
fields = compact ? Collections.singletonList(QUERY_PARAM_FIELDS_COMPACT) : Collections.singletonList(DefaultCollectionGet.QUERY_PARAM_FIELDS_ALL);
QueryParamUtils.configureFieldsDefault(requestContext, fields);
}
return HALCollectionV1Builder.fromPartial(
this.list(
calculatedPageStart,
pageSize,
QueryParamUtils.stripHALStructure(fields),
QueryParamUtils.stripHALStructure(query),
QueryParamUtils.parseSort(sort)),
uriInfo.getRequestUri(),
this.count(QueryParamUtils.stripHALStructure(query)))
.page(page)
.maxPageSize(pageSize)
.compact(compact)
.build();
}
return HALCollectionV2Builder.from(
this.list(
pageStart,
pageSize,
QueryParamUtils.stripHALStructure(fields),
QueryParamUtils.stripHALStructure(query),
QueryParamUtils.parseSort(sort)),
uriInfo.getRequestUri())
.withNavigation(pageStart, pageSize)
.collectionSize(this.count(QueryParamUtils.stripHALStructure(query)))
.build(selected);
}
}

0 comments on commit b32b7be

Please sign in to comment.