New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
o.s.data.domain.Pageable - automatically add @ApiImplicitParams? #755
Comments
I had the same problem in a Spring project and from what I could find there is no "automagical" way to do this. You have two options:
Support for this is debatable. Pageable is a Spring-specific construct and who's to say it will never change? Baking something like this into a general framework sounds counter-productive. |
I agree, I am not suggesting that specific support for Pageable be written in. I was wondering if there was something in the Docket builder where I could configure my bean to say "if you see Pageable, use this class instead", where "this" class could be interpreted as request parameters (in the case of Pageable a class with page, size and sort fields). |
This should be fixed via #845 |
Thanks! |
It seems #845 only adds global parameters to every operation. I've found no way to specify that the parameter should be used only when |
@zdila This was to only added implicit parameters to all operations. In your case it doesn't seem like the right solution. In your case, I would simply use an alternate type rule for |
OK. The description of this issue addresses exactly what I need but the provided solution can't be used. I tried also the alternate type rule, but I can't use it to solve the problem. What is needed is that for eg. |
Assuming that you're creating a concrete pageable object class MyRequest extends AbstractPageRequest {
@JsonCreator
MyRequest(@JsonProperty("page) int page, @JsonProperty("size") int size) { super(...)}
//additional bean properties with getters and setters
}
`` |
Pageable object is being created by Spring MVC. |
In which case you'd create a Jackson mixin |
How can I tell the mixin properties that they should be represented as query paramerers? Currently I have this on many places: @ApiOperation(value = "Find partners")
@ApiImplicitParams({
@ApiImplicitParam(name = "page", dataType = "integer", paramType = "query",
value = "Results page you want to retrieve (0..N)"),
@ApiImplicitParam(name = "size", dataType = "integer", paramType = "query",
value = "Number of records per page."),
@ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query",
value = "Sorting criteria in the format: property(,asc|desc). " +
"Default sort order is ascending. " +
"Multiple sort criteria are supported.")
})
@RequestMapping(value = "/v1/partners", method = RequestMethod.GET)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public List<Partner> findAll(@ApiIgnore final Pageable pageable) {
...
} I want to get rid of |
I think this issue should be reopened. |
I think you're 💯% correct. |
@dilipkrish thanks |
The Spring pageable interface is not recognized by default with Swagger. It is a known issue: springfox/springfox#755 The workaround is to use implicit parameters.
+1 |
Plans for 2.7.1 ? :-) |
Did you try 2.7.0? I think this is covered for spring-data-rest |
Hi @dilipkrish, finally had time to test with 2.7.0 - seems not to be working for me. It's essentially a and does not seem to resolve the properties |
@hartmut-pq Yeah thats the solution for non-spring-data-rest projects. |
Hi folks, any news about this feature ? I also really need it, and I'm thinking about implement it, or wait for release |
@kent2171 Its waiting for contributions. Would love it if you'd be able to help out by implementing it |
Fixed via #2063 |
@dilipkrish , still doesn't work with just plain "spring-data-jpa" on 2.8.0. Only with @florianrusch solution. |
@Herzenkin |
@dilipkrish That's disappointing for us spring-data-jpa people. |
@rhanton Not really sure, how that works. Is there a way to expose an JPA repository directly without having to write a controller or using spring-data-rest? Also its not that it will never be supported, there has just not been a demand for it. |
@dilipkrish , the question is exactly about writing custom controller with Pageable parameters which calls spring-data-jpa repository. It will be useful to "unbox" Pageable object in that case as it works with spring-data-rest repository. |
Oh I see. That makes sense. That is supported via extensibility, you could either do something like how it is supported for spring data rest, or come up with a mixin class on your own and create an alternate type rule. |
I think what @rhanton meant is that the fix doesn't work with basic spring-mvc (and spring-data-jpa for persistence). We still need to include the |
@cbornet in case it wasn't obvious, you can create synthetic mixins as shown in the link above, modified snippet below... private Type pageableMixin() {
return new AlternateTypeBuilder()
.fullyQualifiedClassName(
String.format("%s.generated.%s",
Pageable.class.getPackage().getName(),
Pageable.class.getSimpleName()))
.withProperties(newArrayList(
property(Integer.class, "page"),
property(Integer.class, "limit"),
property(String.class, "sort")
))
.build();
} Will create a rule that will replace Pageable with a mixin class with properties "page, limit, sort" hardcoded. Does that make sense? |
@dilipkrish i want size but i got pageSize when i use (@PageableDefault Pageable pageable) |
The default findAll has page,sort and size , but the endpoint doesnt have a effect for any of the provided values. it returns all the object without paging. below is my pom, <artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
<artifactId>springfox-data-rest</artifactId>
<version>2.8.0</version>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.8.0</version> my repository resource, @RepositoryRestResource
public interface PhenotypeRepository extends CrudRepository<Phenotype, String> {
} |
@91wangmeng you need to create a rule for the |
Please upgrade to 2.9.2 @selvaebi |
Cleanup the existing parameters due to merge. Sadly, reflection is required. import static com.google.common.collect.Lists.newArrayList;
import static springfox.documentation.spi.schema.contexts.ModelContext.inputParam;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.TypeResolver;
import com.google.common.base.Function;
import com.google.common.collect.Sets;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.OperationBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.schema.ModelReference;
import springfox.documentation.schema.ResolvedTypes;
import springfox.documentation.schema.TypeNameExtractor;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.contexts.ModelContext;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spi.service.contexts.ParameterContext;
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class OperationPageableParameterReader implements OperationBuilderPlugin {
private final TypeNameExtractor nameExtractor;
private final ResolvedType pageableType;
private final TypeResolver resolver;
@Autowired
public OperationPageableParameterReader(TypeNameExtractor nameExtractor, TypeResolver resolver) {
this.nameExtractor = nameExtractor;
this.resolver = resolver;
this.pageableType = resolver.resolve(Pageable.class);
}
@Override
@SneakyThrows
public void apply(OperationContext context) {
List<ResolvedMethodParameter> methodParameters = context.getParameters();
List<Parameter> parameters = newArrayList();
for (ResolvedMethodParameter methodParameter : methodParameters) {
ResolvedType resolvedType = methodParameter.getParameterType();
if (!pageableType.equals(resolvedType)) {
continue;
}
ParameterContext parameterContext = new ParameterContext(methodParameter, new ParameterBuilder(),
context.getDocumentationContext(), context.getGenericsNamingStrategy(), context);
Function<ResolvedType, ? extends ModelReference> factory = createModelRefFactory(parameterContext);
ModelReference intModel = factory.apply(resolver.resolve(Integer.TYPE));
ModelReference stringModel = factory.apply(resolver.resolve(List.class, String.class));
parameters.add(new ParameterBuilder().parameterType("query")
.name("page")
.modelRef(intModel)
.description("Results page you want to retrieve (0..N)")
.build());
parameters.add(new ParameterBuilder().parameterType("query")
.name("size")
.modelRef(intModel)
.description("Number of records per page")
.build());
parameters.add(new ParameterBuilder().parameterType("query")
.name("sort")
.modelRef(stringModel)
.allowMultiple(true)
.description("Sorting criteria in the format: property(,asc|desc). "
+ "Default sort order is ascending. " + "Multiple sort criteria are supported.")
.build());
final OperationBuilder operationBuilder = context.operationBuilder();
operationBuilder.parameters(parameters);
Set<String> toDelete = Sets.newLinkedHashSet(Arrays
.asList("offset", "pageNumber", "pageSize", "paged", "sort.sorted", "sort.unsorted", "unpaged"));
final Field field = operationBuilder.getClass().getDeclaredField("parameters");
field.setAccessible(true);
@SuppressWarnings("unchecked")
final List<Parameter> list = (List<Parameter>) field.get(operationBuilder);
field.set(operationBuilder,
list.stream().filter(p -> !toDelete.contains(p.getName())).collect(Collectors.toList()));
}
}
private Function<ResolvedType, ? extends ModelReference> createModelRefFactory(ParameterContext context) {
ModelContext modelContext = inputParam(context.getGroupName(),
context.resolvedMethodParameter().getParameterType(),
context.getDocumentationType(),
context.getAlternateTypeProvider(),
context.getGenericNamingStrategy(),
context.getIgnorableParameterTypes());
return ResolvedTypes.modelRefFactory(modelContext, nameExtractor);
}
@Override
public boolean supports(DocumentationType delimiter) {
return true;
}
} |
@vlsergeyatsbt this is already supported in 2.9.2. Is it not working? |
sorry i used pagingAndSortingRepository , it worked in 2.8.0 , sorry for late reply. |
Hi @dilipkrish , I tested the |
@cbornet i am facing the same problem with AlternateTypeRule, is there any way to set description for pageable parameters ? |
Hi,
I have been looking for but haven't found a way to automatically the implicit parameters of the Pageable parameter. It would be great to have the page, size and sort parameters automatically added to the Swagger documentation. I have tried Docket#directModelSubstitute but this has not worked.
Any insight to this?
The text was updated successfully, but these errors were encountered: