Skip to content

fix: skip WebSocket onHandshake operation on publish - #318

Merged
Alexander Zaslonov (azaslonov) merged 3 commits into
Azure:mainfrom
Alexey-Zheltov:fix/websocket-onhandshake-skip
Oct 10, 2026
Merged

Alexander Zaslonov (azaslonov) merged 3 commits into
Azure:mainfrom
Alexey-Zheltov:fix/websocket-onhandshake-skip

Conversation

@Alexey-Zheltov

Copy link
Copy Markdown
Collaborator

Summary

apiops publish fails with HTTP 400 for WebSocket APIs:
PUT apioperation/<api>/onHandshake: 'urlTemplate' should not be empty.

APIM auto-creates a single system-managed onHandshake operation with an empty
urlTemplate when a type: websocket API is created. The extractor persists it
as-is, and the publisher (no spec import for WebSocket) re-PUTs it, which APIM rejects.

  • publishResource now skips ApiOperation descriptors whose parent API artifact
    (with overrides applied) has properties.type === 'websocket', logging the reason
    and reporting the resource as SKIP. Done in publishResource so both the
    publishApi child path and the direct incremental path are covered.
  • Operation policies (operations/onHandshake/policies/policy) are still published.
  • Unit tests: skip for websocket parent, PUT for non-websocket parent, PUT when the
    parent artifact is missing.

Verified APIM behaviour (api-version 2024-05-01)

Call on operations/onHandshake Result
PUT / PATCH with urlTemplate: "" 400 'urlTemplate' should not be empty
PUT any other operation 400 Operation entity cannot be defined by user for web socket api type
PUT operations/onHandshake/policies/policy 200

Validation

  • End-to-end: WebSocket API + onHandshake policy → apiops extract → apiops publish
    to a second APIM instance: PUT api, SKIP apioperation, PUT apioperationpolicy,
    exit 0; policy content matches on the target.
  • npm run lint, tsc --noEmit, tests/unit/services/resource-publisher.test.ts (87 passed).
  • Code review per .squad/ceremonies.md requested.

Related Issue(s)

Fixes #317

APIM auto-creates a single system-managed `onHandshake` operation with an
empty urlTemplate for `type: websocket` APIs. PUT/PATCH of that operation
with the extracted `urlTemplate: ""` fails with HTTP 400
("'urlTemplate' should not be empty"), and APIM rejects any user-defined
operation for WebSocket APIs. Skip ApiOperation PUTs when the parent API
artifact declares `type: websocket`; the operation policy is still published.

Fixes Azure#317
Copilot AI balanced review requested due to automatic review settings October 9, 2026 19:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Parent artifact read failures are incorrectly suppressed, potentially masking invalid artifacts and triggering the original APIM error.

1 open finding
What changed in this PR

Prevents publishing APIM-managed WebSocket operations while preserving operation-policy publishing.

Changes:

  • Detects WebSocket parent APIs and skips operation PUTs.
  • Adds coverage for WebSocket, non-WebSocket, and missing-parent cases.
File Description
src/​services/​resource-publisher.ts Adds WebSocket operation detection and skipping.
tests/​unit/​services/​resource-publisher.test.ts Tests the new publishing behavior.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/services/resource-publisher.ts Resolved
…operations

Let readResource errors propagate to publishResource's failure handling instead
of treating them as a missing parent, which would fall through to a PUT that
APIM rejects. A missing parent (undefined) still allows the operation PUT.

Addresses review feedback on Azure#318.
Copilot AI balanced review requested due to automatic review settings October 9, 2026 19:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Dry-run still reports WebSocket operations as PUTs instead of matching the new SKIP behavior.

1 open finding
1 resolved since last review

🧠 Review effort: Balanced

Comment thread src/services/resource-publisher.ts Resolved
Move the WebSocket operation check into evaluateResourceEligibility and apply it
in planDryRunPublications for both the API-child and direct descriptor paths, so
`--dry-run` reports SKIP for `onHandshake` exactly as a real publish does.

Addresses review feedback on Azure#318.
Copilot AI balanced review requested due to automatic review settings October 9, 2026 19:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation covers both publication paths, preserves policy publishing, and includes focused regression tests.

1 open finding

🧠 Review effort: Balanced

@azaslonov
Alexander Zaslonov (azaslonov) merged commit e8b704f into Azure:main Oct 10, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ApiOps CLI Publisher fails with empty urlTemplate error.

3 participants