Skip to content

Commit 3e13fb8

Browse files
authored
generate protocol-specific event payload (#554)
* expose serializeInputEventDocumentPayload() to generate protocol-specific event payload * remove the event headers when serializing implicit event payload * address feedbacks
1 parent 062ebfa commit 3e13fb8

File tree

1 file changed

+45
-13
lines changed

1 file changed

+45
-13
lines changed

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

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,29 @@ protected abstract void serializeInputDocumentBody(
13501350
List<HttpBinding> documentBindings
13511351
);
13521352

1353+
/**
1354+
* Writes the code needed to serialize an event payload as a protocol-specific document.
1355+
*
1356+
* <p>Implementations of this method are expected to set a value to the ${@code message.body} property.
1357+
* The value set is expected to by a JavaScript ${@code Uint8Array} type and is to be encoded as the
1358+
* event payload.
1359+
*
1360+
* <p>Three parameters will be available in scope:
1361+
* <ul>
1362+
* <li>{@code body}: The serialized event payload object that needs to be transformed to binary data</li>
1363+
* <li>{@code message: <T>}: The partially constructed event message.</li>
1364+
* <li>{@code context: SerdeContext}: a TypeScript type containing context and tools for type serde.</li>
1365+
* </ul>
1366+
*
1367+
* <p>For example:
1368+
*
1369+
* <pre>{@code
1370+
* message.body = context.utf8Decoder(JSON.stringify(body));
1371+
* }</pre>
1372+
* @param context The generation context.
1373+
*/
1374+
protected abstract void serializeInputEventDocumentPayload(GenerationContext context);
1375+
13531376
/**
13541377
* Writes the code needed to serialize a protocol output document.
13551378
*
@@ -1611,25 +1634,34 @@ private void writeEventBody(GenerationContext context, StructureShape event) {
16111634
TypeScriptWriter writer = context.getWriter();
16121635
Model model = context.getModel();
16131636
List<MemberShape> payloadMembers = event.getAllMembers().values().stream()
1614-
.filter(member -> member.hasTrait(EventPayloadTrait.class)).collect(Collectors.toList());
1615-
List<MemberShape> documentMembers = event.getAllMembers().values().stream()
1616-
.filter(member -> !member.hasTrait(EventHeaderTrait.class)
1617-
&& !member.hasTrait(EventPayloadTrait.class))
1637+
.filter(member -> member.hasTrait(EventPayloadTrait.class))
16181638
.collect(Collectors.toList());
1619-
if (!payloadMembers.isEmpty()) {
1620-
// Write event payload if exists. There is at most 1 payload member.
1639+
Shape payloadShape = payloadMembers.isEmpty()
1640+
? event // implicit payload
1641+
: model.expectShape(payloadMembers.get(0).getTarget());
1642+
if (payloadShape instanceof BlobShape || payloadShape instanceof StringShape) {
1643+
// Since event itself must be a structure shape, so string or blob payload member must has eventPayload
1644+
// trait explicitly.
16211645
MemberShape payloadMember = payloadMembers.get(0);
1622-
String memberName = payloadMember.getMemberName();
1646+
String payloadMemberName = payloadMember.getMemberName();
16231647
writer.write("message.body = $L || message.body;",
1624-
getInputValue(context, Location.PAYLOAD, "input." + memberName, payloadMember,
1648+
getInputValue(context, Location.PAYLOAD, "input." + payloadMemberName, payloadMember,
16251649
model.expectShape(payloadMember.getTarget())));
1626-
} else if (!documentMembers.isEmpty()) {
1627-
// Write event document bindings if exist.
1650+
} else if (payloadShape instanceof StructureShape || payloadShape instanceof UnionShape) {
1651+
// handle implicit event payload by removing members with eventHeader trait.
1652+
for (MemberShape memberShape : event.members()) {
1653+
if (memberShape.hasTrait(EventHeaderTrait.class)) {
1654+
writer.write("delete input[$S]", memberShape.getMemberName());
1655+
}
1656+
}
16281657
SymbolProvider symbolProvider = context.getSymbolProvider();
1629-
Symbol symbol = symbolProvider.toSymbol(event);
1630-
// Use normal structure serializer instead of event serializer to serialize document body.
1658+
Symbol symbol = symbolProvider.toSymbol(payloadShape);
16311659
String serFunctionName = ProtocolGenerator.getSerFunctionName(symbol, context.getProtocolName());
1632-
writer.write("message.body = $L(input, context);", serFunctionName);
1660+
writer.write("const body = $L(input, context);", serFunctionName);
1661+
serializeInputEventDocumentPayload(context);
1662+
} else {
1663+
throw new CodegenException(String.format("Unexpected shape type bound to event payload: `%s`",
1664+
payloadShape.getType()));
16331665
}
16341666
}
16351667

0 commit comments

Comments
 (0)