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

Update semantic validation of OPTIONS #890

Merged
merged 1 commit into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -45,20 +45,27 @@ public final class HttpMethodSemanticsValidator extends AbstractValidator {
* <li>(Boolean) isReadonly</li>
* <li>(Boolean) isIdempotent</li>
* <li>(Boolean) allowsRequestPayload</li>
* <li>(Boolean) warningMessageWhenModeled</li>
* </ul>
*
* <p>Setting any of the Boolean properties to {@code null} means that
* the validator will have no enforced semantic on a specific property.
*/
private static final Map<String, HttpMethodSemantics> EXPECTED = MapUtils.of(
"GET", new HttpMethodSemantics(true, false, false),
"HEAD", new HttpMethodSemantics(true, false, false),
"OPTIONS", new HttpMethodSemantics(true, false, false),
"TRACE", new HttpMethodSemantics(true, false, false),
"POST", new HttpMethodSemantics(false, null, true),
"DELETE", new HttpMethodSemantics(false, true, false),
"PUT", new HttpMethodSemantics(false, true, true),
"PATCH", new HttpMethodSemantics(false, null, true));
"GET", new HttpMethodSemantics(true, false, false, null),
"HEAD", new HttpMethodSemantics(true, false, false, null),
"OPTIONS", new HttpMethodSemantics(true, false, true,
"OPTIONS requests are typically used as part of CORS and should not be modeled explicitly. They "
+ "are an implementation detail that should not appear in generated client or server code. "
+ "Instead, tooling should use the `cors` trait on a service to automatically configure CORS on "
+ "clients and servers. It is the responsibility of service frameworks and API gateways to "
+ "automatically manage OPTIONS requests. For example, OPTIONS requests are automatically "
+ "created when using Smithy models with Amazon API Gateway."),
"TRACE", new HttpMethodSemantics(true, false, false, null),
"POST", new HttpMethodSemantics(false, null, true, null),
"DELETE", new HttpMethodSemantics(false, true, false, null),
"PUT", new HttpMethodSemantics(false, true, true, null),
"PATCH", new HttpMethodSemantics(false, null, true, null));

@Override
public List<ValidationEvent> validate(Model model) {
Expand Down Expand Up @@ -88,6 +95,11 @@ private List<ValidationEvent> validateOperation(
}

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(
Expand Down Expand Up @@ -123,11 +135,18 @@ private static final class HttpMethodSemantics {
private final Boolean isReadonly;
private final Boolean isIdempotent;
private final Boolean allowsRequestPayload;
private final String warningWhenModeled;

private HttpMethodSemantics(Boolean isReadonly, Boolean isIdempotent, Boolean allowsRequestPayload) {
private HttpMethodSemantics(
Boolean isReadonly,
Boolean isIdempotent,
Boolean allowsRequestPayload,
String warningWhenModeled
) {
this.isReadonly = isReadonly;
this.isIdempotent = isIdempotent;
this.allowsRequestPayload = allowsRequestPayload;
this.warningWhenModeled = warningWhenModeled;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
[WARNING] ns.foo#G: This operation uses the `POST` method in the `http` trait, but is marked with the readonly trait | HttpMethodSemantics
[WARNING] ns.foo#H: This operation uses the `DELETE` method in the `http` trait, but is not marked with the idempotent trait | HttpMethodSemantics
[WARNING] ns.foo#I: This operation uses the `GET` method in the `http` trait, but is not marked with the readonly trait | HttpMethodSemantics
[WARNING] ns.foo#Options: OPTIONS requests are typically used as part of CORS and should not be modeled explicitly. They are an implementation detail that should not appear in generated client or server code. Instead, tooling should use the `cors` trait on a service to automatically configure CORS on clients and servers. It is the responsibility of service frameworks and API gateways to automatically manage OPTIONS requests. For example, OPTIONS requests are automatically created when using Smithy models with Amazon API Gateway. | HttpMethodSemantics
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,23 @@
},
"smithy.api#idempotent": {}
}
},
"ns.foo#Options": {
"type": "operation",
"traits": {
"smithy.api#http": {
"method": "OPTIONS",
"uri": "/options"
},
"smithy.api#readonly": {}
},
"input": {
"target": "ns.foo#OptionsInput"
}
},
"ns.foo#OptionsInput": {
"type": "structure",
"members": {}
}
}
}