Skip to content
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

Development: Enforce Usage of Optional<T> Over @RequestParam(required = false) in Method Parameters #9146

Closed
Changes from 5 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
396408a
Add ArchTest to check method parameters for RequestParam annotation w…
pvlov Jul 28, 2024
f4b291d
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Jul 28, 2024
227743e
Remove unnecessary newline
pvlov Jul 28, 2024
4f0aaf8
add check if defaultValue is set
pvlov Jul 28, 2024
ce683bd
check if defaultValue is actually set
pvlov Jul 28, 2024
732f879
Use ValueConstants over copied literal
pvlov Jul 29, 2024
a84cea3
Added check for required set to false on Optional<T> param
pvlov Jul 29, 2024
aeff3e8
Fix some of the Violations
pvlov Jul 29, 2024
73798a9
Remove check for primitive classes
pvlov Jul 29, 2024
57ec751
Complete the fix of the Violations
pvlov Jul 29, 2024
028e4fb
fix test failures
pvlov Jul 30, 2024
43b2746
Fix last failing Tests, replace Min and Max with Range Annotation
pvlov Aug 5, 2024
3ccb9c0
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 5, 2024
14943bc
Incorporate feedback: Refactor method and remove required = false whe…
pvlov Aug 6, 2024
1e6df05
Incorporate automatic reviews
pvlov Aug 6, 2024
2579c41
Adding changes from review
pvlov Aug 6, 2024
5581732
revert getComplaintByCourseId and fix param name
pvlov Aug 6, 2024
86fae49
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 10, 2024
7ec6c45
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 11, 2024
ca8ac55
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 15, 2024
f314a86
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 17, 2024
c6f0206
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 20, 2024
3576f39
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 21, 2024
a4b06a3
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 26, 2024
cc8534f
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Aug 30, 2024
015634a
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Sep 8, 2024
19d6777
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Sep 20, 2024
90a7fb3
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Sep 26, 2024
0acbb3f
Merge remote-tracking branch 'upstream/develop' into chore/testing/ad…
pvlov Oct 7, 2024
133e730
Merge branch 'develop' into chore/testing/add-check-for-required-fals…
pvlov Oct 14, 2024
091e01f
doc: Add documentation for the use of Optionals to the server guidelines
pvlov Oct 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.annotation.JsonInclude;
Expand All @@ -63,7 +64,9 @@
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.JavaEnumConstant;
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.JavaParameter;
import com.tngtech.archunit.core.domain.properties.HasAnnotations;
import com.tngtech.archunit.core.domain.properties.HasType;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.ConditionEvents;
Expand Down Expand Up @@ -289,6 +292,37 @@ public void check(T item, ConditionEvents events) {
};
}

@Test
void testNoRequiredFalseOnMethodParams() {
methods().should(notHaveRequestParamWithRequiredFalse()).check(allClasses);
}

private ArchCondition<JavaMethod> notHaveRequestParamWithRequiredFalse() {
pvlov marked this conversation as resolved.
Show resolved Hide resolved
return new ArchCondition<>("Do not use 'required = false' with @RequestParam") {

@Override
public void check(final JavaMethod method, final ConditionEvents events) {

final String defaultDefaultValue = "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
pvlov marked this conversation as resolved.
Show resolved Hide resolved

final var violated = method.getParameters().stream().map(JavaParameter::getAnnotations).flatMap(Set::stream).filter(HasType.Predicates.rawType(RequestParam.class))
.filter(annotation -> {
// if there is a default value set, then required false does not need to be checked for
// The Annotation sets a default value for defaultValue so we have to make sure it is not equal to that
final String value = (String) annotation.get("defaultValue").orElse(defaultDefaultValue);
return defaultDefaultValue.equals(value);
}).map(annotation -> annotation.get("required").orElse(true)) // if not set, the default is true
.map(Boolean.class::cast) // since we filter for the annotation and field we know this cast is safe!
.anyMatch(required -> !required);

if (violated) {
final String message = String.format("Method %s uses 'required = false', use Optional<T> instead!", method.getFullName());
events.add(SimpleConditionEvent.violated(method, message));
}
}
};
}
pvlov marked this conversation as resolved.
Show resolved Hide resolved

private static ArchCondition<JavaClass> beProfileAnnotated() {
return new ArchCondition<>("be annotated with @Profile") {

Expand Down
Loading