in smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/HttpMethodSemanticsValidator.java [85:145]
private List<ValidationEvent> validateOperation(
HttpBindingIndex bindingIndex,
OperationShape shape,
HttpTrait trait
) {
String method = trait.getMethod().toUpperCase(Locale.US);
List<ValidationEvent> events = new ArrayList<>();
if (!EXPECTED.containsKey(method)) {
return events;
}
HttpMethodSemantics semantics = EXPECTED.get(method);
if (semantics.warningWhenModeled != null) {
events.add(warning(shape, trait, semantics.warningWhenModeled));
}
boolean isReadonly = shape.getTrait(ReadonlyTrait.class).isPresent();
if (semantics.isReadonly != null && semantics.isReadonly != isReadonly) {
events.add(warning(shape, trait, String.format(
"This operation uses the `%s` method in the `http` trait, but %s marked with the readonly trait",
method, isReadonly ? "is" : "is not")));
}
boolean isIdempotent = shape.getTrait(IdempotentTrait.class).isPresent();
if (semantics.isIdempotent != null && semantics.isIdempotent != isIdempotent) {
events.add(warning(shape, trait, String.format(
"This operation uses the `%s` method in the `http` trait, but %s marked with the idempotent trait",
method, isIdempotent ? "is" : "is not")));
}
List<HttpBinding> payloadBindings = bindingIndex.getRequestBindings(shape, HttpBinding.Location.PAYLOAD);
List<HttpBinding> documentBindings = bindingIndex.getRequestBindings(shape, HttpBinding.Location.DOCUMENT);
if (semantics.allowsRequestPayload != null && !semantics.allowsRequestPayload) {
if (!payloadBindings.isEmpty()) {
events.add(danger(shape, trait, String.format(
"This operation uses the `%s` method in the `http` trait, but the `%s` member is sent as the "
+ "payload of the request because it is marked with the `httpPayload` trait. Many HTTP "
+ "clients do not support payloads with %1$s requests. Consider binding this member to "
+ "other parts of the HTTP request such as a query string parameter using the `httpQuery` "
+ "trait, a header using the `httpHeader` trait, or a path segment using the `httpLabel` "
+ "trait.",
method, payloadBindings.get(0).getMemberName()
)));
} else if (!documentBindings.isEmpty()) {
events.add(danger(shape, trait, String.format(
"This operation uses the `%s` method in the `http` trait, but the following members "
+ "are sent as part of the payload of the request: %s. These members are sent as part "
+ "of the payload because they are not explicitly configured to be sent in headers, in the "
+ "query string, or in a URI segment. Many HTTP clients do not support payloads with %1$s "
+ "requests. Consider binding these members to other parts of the HTTP request such as "
+ "query string parameters using the `httpQuery` trait, headers using the `httpHeader` "
+ "trait, or URI segments using the `httpLabel` trait.",
method, ValidationUtils.tickedList(documentBindings.stream().map(HttpBinding::getMemberName))
)));
}
}
return events;
}