A partner republishes its WSDL 1.1 contract with a new targetNamespace for version 2 — what changes for your generated client, and what changes on the wire?
answer
- two targetNamespaces, not one
- which QNames ever reach the wire
- Body child, SOAPAction, address
- big bang versus compatible evolution
basics
~20 sThe WSDL's targetNamespace names portTypes, messages, bindings and services, which a generated client is built around but a document/literal message never carries; the wire changes only if the schema namespace, the soapAction values or the address change too.
solid answer
~50 sFirst ask *which* targetNamespace moved. The one on `wsdl:definitions` qualifies the names of messages, portTypes, bindings and services — the names a generator typically turns into code names, so regenerating produces a new, incompatible client API and a rebuild. But in a document/literal binding none of those names travels: the Body carries the element a part references, qualified by its **schema's** targetNamespace, plus the `soapAction` and the port address. If only the WSDL namespace changed, v1 and v2 requests carry the same Body element, action and address, and old clients keep working — which also means the bump signals nothing to them. If the schema namespace changed, every Body element's name changes, and the service must keep serving v1 or reject it during a handover. The WSDL 2.0 Primer makes the same point: to signal incompatibility, change something that appears in the message.
code
xml · 14 lines<definitions name="Payments"
targetNamespace="http://example.com/payments/wsdl/v2"
xmlns:tns="http://example.com/payments/wsdl/v2"
xmlns:pay="http://example.com/payments/schema/v1"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<!-- types: xsd:schema targetNamespace="http://example.com/payments/schema/v1" -->
<message name="AuthorizeIn">
<part name="body" element="pay:AuthorizeRequest"/>
</message>
<!-- portType tns:PaymentsPortType and binding tns:PaymentsSoap here -->
<!-- soap:operation soapAction="http://example.com/payments/Authorize" -->
</definitions>
<!-- On the wire, the Body child is still pay:AuthorizeRequest in .../schema/v1 -->go deeper
Know that a WSDL usually carries two target namespaces — one for its own definitions, one for the schema of its messages.
Explain which names a generated client is built from and which three things a SOAP request actually carries: address, action and Body element.
Given a partner's v2 contract, diff schema namespace, soapAction and address to predict whether running clients break, and plan a handover rather than a flag day.
Choose a versioning policy for a contract portfolio — compatible evolution for additive changes, new schema namespaces for breaking ones — and weigh the cost of cloned interfaces.
## Two namespaces that look alike A WSDL 1.1 contract usually carries at least two `targetNamespace` attributes, and teams often bump them together without asking what each one does. | Attribute on | Qualifies | Appears in a document/literal message? | |---|---|---| | `wsdl:definitions` | names of `message`, `portType`, `binding`, `service`, `port` | no | | `xsd:schema` (in `types` or an imported XSD) | element and type declarations that parts reference | yes — the Body's child element is one of these | The WSDL 1.1 Note lets `targetNamespace` on `definitions` be optional (it MUST NOT be relative when present), and references between WSDL definitions are QNames resolved against it. Nothing in that resolution reaches the wire. ## What a generated client is built from A generator reads both namespaces, but uses them differently: - **WSDL names** — portType, operation, binding, service — usually become the names of the generated interface, its methods and its service accessor. How a namespace maps to a code module or package is each toolkit's choice, but in practice a new WSDL namespace yields new generated names, so application code compiled against v1 no longer compiles against v2. - **Schema declarations** become the data types the stub serialises; their namespace is written into every element the stub produces. - **Binding and port details** — the `soapAction` of each `soap:operation`, and `soap:address` — become constants the stub sends with every call. So regenerating after any namespace bump is a build-time event for the client team, whatever happens on the wire. ## What actually travels For a SOAP request over HTTP, three things carry the contract: 1. **The endpoint URI** — from the port's `soap:address`. 2. **The action** — the `soapAction` declared on `soap:operation`, sent by SOAP 1.1 as the `SOAPAction` header. Its value is whatever URI the binding author wrote; it may or may not embed a namespace. 3. **The Body content** — in document style, the parts appear directly under the SOAP Body, so the Body's child is the XSD element the part references, qualified by that **schema's** targetNamespace. In rpc style the parts sit under a wrapper element named after the operation, whose namespace is the `namespace` attribute of `soap:body`; authors often set that to the WSDL's own namespace, and then a WSDL namespace bump does reach the wire. ## Reading the partner's version 2 Before planning anything, diff the two documents along those three lines: | What changed | Wire effect | Running v1 clients | |---|---|---| | Only the WSDL `targetNamespace` | none in document/literal | keep working; only regeneration is affected | | `soapAction` values | new action header | may be dispatched differently or rejected, depending on the service | | Schema `targetNamespace` | every Body element renamed | requests no longer match v2's declarations; the service must route or reject them | | `soap:address` | new endpoint | keep calling the old address until reconfigured | A namespace bump that changes nothing on the wire is a pure client rebuild with no protocol meaning; one that changes the schema namespace is a breaking change, whatever the release notes call it. ## Choosing a versioning signal The WSDL 2.0 Primer, whose reasoning applies equally to 1.1, describes two approaches: - **Compatible evolution** — limit changes to backward- or forward-compatible ones: add a binding, add an operation, add optional content where the schema allows it (optional elements, `xs:any`), or carry new data in optional SOAP headers, which a receiver that does not understand them ignores unless a header is marked `mustUnderstand`. - **Big bang** — any change implies a new namespace: a changed interface gets a new interface namespace, changed message content a new message namespace. Clients can tell at a glance that something changed, but the Primer warns this leads to many cloned interfaces. The Primer also notes that renaming an interface or an operation does not affect the messages exchanged, so it cannot signal incompatibility; for SOAP over HTTP, only the endpoint URI, the SOAP action or the message content can. A sensible combination is to keep the WSDL namespace stable for additive changes, change the **schema** namespace (or the element names) for breaking payload changes, and run v1 and v2 side by side — separate ports or separate endpoints — through a handover window, as the Primer's discussion of incompatible change suggests.
- When is changing the schema namespace the right versioning move?When the message content changes incompatibly — a new mandatory element, a removed or retyped one. Every Body element then carries the new namespace, so a v1 request can no longer be mistaken for v2: the service can route it to v1 handling or answer with a fault. Plan a handover in which both versions are served until consumers have moved.
- What can a partner change in a WSDL 1.1 contract without any namespace change?Additive, compatible changes: a new binding or port, a new operation in the portType, optional elements where the schema leaves room for them, or optional SOAP headers that receivers may ignore. Existing clients keep sending the same messages; new clients regenerate to use the additions.
- Does a WSDL targetNamespace change ever reach the wire?It can in rpc style. There the SOAP Body holds a wrapper element named after the operation, and its namespace comes from the `namespace` attribute of `soap:body`. When the binding author sets that attribute to the WSDL's own namespace, bumping the WSDL namespace renames the wrapper, and old clients' requests stop matching.
saying these in an interview costs you the question
- Bumping the WSDL targetNamespace makes every running v1 client fail at once.
- The Body element's namespace always comes from the WSDL targetNamespace.
- Renaming the portType or an operation tells old clients they are incompatible.
- Every change to a WSDL contract requires a new namespace.
- The SOAP envelope namespace carries the service contract's version.