diff --git a/.changeset/tender-ducks-act.md b/.changeset/tender-ducks-act.md new file mode 100644 index 00000000000..a12392f93de --- /dev/null +++ b/.changeset/tender-ducks-act.md @@ -0,0 +1,5 @@ +--- +"@smithy/core": patch +--- + +idempotency token generation for HttpBindingProtocol diff --git a/packages/core/src/submodules/protocols/HttpBindingProtocol.spec.ts b/packages/core/src/submodules/protocols/HttpBindingProtocol.spec.ts index 4b3001a695b..a6e37c1b3dd 100644 --- a/packages/core/src/submodules/protocols/HttpBindingProtocol.spec.ts +++ b/packages/core/src/submodules/protocols/HttpBindingProtocol.spec.ts @@ -14,6 +14,7 @@ import type { SerdeFunctions, ShapeDeserializer, ShapeSerializer, + StaticStructureSchema, StringSchema, TimestampDefaultSchema, TimestampEpochSecondsSchema, @@ -206,4 +207,41 @@ describe(HttpBindingProtocol.name, () => { header: "header-value", }); }); + + it("should fill in undefined idempotency tokens", async () => { + const protocol = new StringRestProtocol(); + const request = await protocol.serializeRequest( + op( + "", + "", + { + http: ["GET", "/{labelToken}/Operation", 200], + }, + [ + 3, + "ns", + "Struct", + 0, + ["name", "queryToken", "labelToken", "headerToken"], + [ + 0, + [0, { idempotencyToken: 1, httpQuery: "token" }], + [0, { idempotencyToken: 1, httpLabel: 1 }], + [0, { idempotencyToken: 1, httpHeader: "header-token" }], + ], + ] satisfies StaticStructureSchema, + "unit" + ), + { + Name: "my-name", + }, + { + endpoint: async () => parseUrl("https://localhost/custom"), + } as any + ); + + expect(request.query?.token).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/); + expect(request.path).toMatch(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/); + expect(request.headers?.["header-token"]).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/); + }); }); diff --git a/packages/core/src/submodules/protocols/HttpBindingProtocol.ts b/packages/core/src/submodules/protocols/HttpBindingProtocol.ts index 8cfec4482b4..77c423d18fe 100644 --- a/packages/core/src/submodules/protocols/HttpBindingProtocol.ts +++ b/packages/core/src/submodules/protocols/HttpBindingProtocol.ts @@ -78,7 +78,7 @@ export abstract class HttpBindingProtocol extends HttpProtocol { const memberTraits = memberNs.getMergedTraits() ?? {}; const inputMemberValue = input[memberName]; - if (inputMemberValue == null) { + if (inputMemberValue == null && !memberNs.isIdempotencyToken()) { continue; }