Skip to content

Commit f851ade

Browse files
trivikrsrchase
authored andcommitted
Consume httpQueryParams trait (smithy-lang#311)
1 parent ff1992f commit f851ade

File tree

1 file changed

+64
-12
lines changed

1 file changed

+64
-12
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/integration/HttpBindingProtocolGenerator.java

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -655,36 +655,55 @@ private boolean writeRequestQueryString(
655655
HttpTrait trait
656656
) {
657657
TypeScriptWriter writer = context.getWriter();
658-
SymbolProvider symbolProvider = context.getSymbolProvider();
659658
List<HttpBinding> queryBindings = bindingIndex.getRequestBindings(operation, Location.QUERY);
659+
List<HttpBinding> queryParamsBindings = bindingIndex.getRequestBindings(operation, Location.QUERY_PARAMS);
660660

661661
// Build the initial query bag.
662662
Map<String, String> queryLiterals = trait.getUri().getQueryLiterals();
663-
if (!queryLiterals.isEmpty() || !queryBindings.isEmpty()) {
663+
if (!queryLiterals.isEmpty() || !queryBindings.isEmpty() || !queryParamsBindings.isEmpty()) {
664664
writer.openBlock("const query: any = {", "};", () -> {
665665
if (!queryLiterals.isEmpty()) {
666666
// Write any query literals present in the uri.
667667
queryLiterals.forEach((k, v) -> writer.write("$S: $S,", k, v));
668668
}
669+
// Handle any additional query params bindings.
670+
// If query string parameter is also present in httpQuery, it would be overwritten.
671+
// Serializing HTTP messages https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html#serializing-http-messages
672+
if (!queryParamsBindings.isEmpty()) {
673+
SymbolProvider symbolProvider = context.getSymbolProvider();
674+
String memberName = symbolProvider.toMemberName(queryParamsBindings.get(0).getMember());
675+
writer.write("...(input.$1L !== undefined && input.$1L),", memberName);
676+
}
669677
// Handle any additional query bindings.
670678
if (!queryBindings.isEmpty()) {
671-
Model model = context.getModel();
672679
for (HttpBinding binding : queryBindings) {
673-
String memberName = symbolProvider.toMemberName(binding.getMember());
674-
writer.addImport("extendedEncodeURIComponent", "__extendedEncodeURIComponent",
675-
"@aws-sdk/smithy-client");
676-
Shape target = model.expectShape(binding.getMember().getTarget());
677-
String queryValue = getInputValue(context, binding.getLocation(), "input." + memberName,
678-
binding.getMember(), target);
679-
writer.write("...(input.$L !== undefined && { $S: $L }),", memberName,
680-
binding.getLocationName(), queryValue);
680+
writeRequestQueryParam(context, binding);
681681
}
682682
}
683683
});
684684
}
685685

686686
// Any binding or literal means we generated a query bag.
687-
return !queryBindings.isEmpty() || !queryLiterals.isEmpty();
687+
return !queryBindings.isEmpty() || !queryLiterals.isEmpty() || !queryParamsBindings.isEmpty();
688+
}
689+
690+
private void writeRequestQueryParam(
691+
GenerationContext context,
692+
HttpBinding binding
693+
) {
694+
Model model = context.getModel();
695+
TypeScriptWriter writer = context.getWriter();
696+
SymbolProvider symbolProvider = context.getSymbolProvider();
697+
698+
String memberName = symbolProvider.toMemberName(binding.getMember());
699+
writer.addImport("extendedEncodeURIComponent", "__extendedEncodeURIComponent",
700+
"@aws-sdk/smithy-client");
701+
702+
Shape target = model.expectShape(binding.getMember().getTarget());
703+
String queryValue = getInputValue(context, binding.getLocation(), "input." + memberName,
704+
binding.getMember(), target);
705+
writer.write("...(input.$L !== undefined && { $S: $L }),", memberName,
706+
binding.getLocationName(), queryValue);
688707
}
689708

690709
private void writeRequestHeaders(
@@ -867,6 +886,8 @@ protected String getInputValue(
867886
return getCollectionInputParam(context, bindingType, dataSource, (CollectionShape) target);
868887
} else if (target instanceof StructureShape || target instanceof UnionShape) {
869888
return getNamedMembersInputParam(context, bindingType, dataSource, target);
889+
} else if (target instanceof MapShape) {
890+
return getMapInputParam(context, bindingType, dataSource, (MapShape) target);
870891
}
871892

872893
throw new CodegenException(String.format(
@@ -957,6 +978,7 @@ private String getCollectionInputParam(
957978
case HEADER:
958979
return iteratedParam + ".join(', ')";
959980
case QUERY:
981+
case QUERY_PARAMS:
960982
return iteratedParam;
961983
default:
962984
throw new CodegenException("Unexpected collection binding location `" + bindingType + "`");
@@ -1000,6 +1022,36 @@ private String getNamedMembersInputParam(
10001022
}
10011023
}
10021024

1025+
/**
1026+
* Given context and a source of data, generate an input value provider for the
1027+
* map.
1028+
*
1029+
* @param context The generation context.
1030+
* @param bindingType How this value is bound to the operation input.
1031+
* @param dataSource The in-code location of the data to provide an input of
1032+
* ({@code input.foo}, {@code entry}, etc.)
1033+
* @param target The shape of the value being provided.
1034+
* @return Returns a value or expression of the input collection.
1035+
*/
1036+
private String getMapInputParam(
1037+
GenerationContext context,
1038+
Location bindingType,
1039+
String dataSource,
1040+
MapShape target
1041+
) {
1042+
Model model = context.getModel();
1043+
MemberShape mapMember = target.getValue();
1044+
SymbolProvider symbolProvider = context.getSymbolProvider();
1045+
1046+
String valueString = getInputValue(context, bindingType, "value", mapMember,
1047+
model.expectShape(mapMember.getTarget()));
1048+
return "Object.entries(" + dataSource + " || {}).reduce("
1049+
+ "(acc: any, [key, value]: [string, " + symbolProvider.toSymbol(mapMember) + "]) => ({"
1050+
+ "...acc,"
1051+
+ "[key]: " + valueString + ","
1052+
+ "}), {})";
1053+
}
1054+
10031055
/**
10041056
* Given context and a source of data, generate an input value provider for the
10051057
* shape. This uses the format specified, converting to strings when in a header,

0 commit comments

Comments
 (0)