Урок 07.03: SOAP и WSDL — «Enterprise-стандарт» интеграции
Цель урока
Познакомиться с протоколом SOAP (Simple Object Access Protocol) и языком описания веб-сервисов WSDL (Web Services Description Language). Понять, чем SOAP принципиально отличается от REST, в каких сценариях он остаётся стандартом де-факто (финансы, госсектор, ERP/CRM), и как аналитику читать WSDL-контракты, проектировать SOAP-интеграции и избегать типовых ошибок. Особый фокус: строение SOAP-конверта, структура WSDL и экосистема WS-* стандартов (Security, AtomicTransaction, ReliableMessaging).
Ключевые понятия
| Термин | Определение |
|---|---|
| SOAP | Simple Object Access Protocol — протокол обмена структурированными сообщениями в формате XML |
| WSDL | Web Services Description Language — язык описания контракта веб-сервиса (что умеет сервис, какие форматы данных, как к нему обращаться) |
| SOAP-Envelope | Корневой XML-элемент SOAP-сообщения, «конверт», внутри которого Header и Body |
| SOAP-Header | Необязательная часть конверта — метаданные (аутентификация, транзакция, маршрутизация) |
| SOAP-Body | Основная часть — данные запроса/ответа (например, CreateTask, GetTaskResponse) |
| Namespace (пространство имён) | Механизм XML для разграничения элементов из разных схем — сердце SOAP-совместимости |
| Binding | Привязка: как SOAP-сообщение передаётся по сети (HTTP, JMS, SMTP); чаще всего — HTTP + POST |
| PortType (Interface) | Набор операций, которые предоставляет веб-сервис (аналог interface в Java/C#) |
| Operation | Конкретный метод веб-сервиса (например, createTask, getTaskById) |
| WS-* | Семейство стандартов поверх SOAP: WS-Security, WS-AtomicTransaction, WS-ReliableMessaging |
| XSD | XML Schema Definition — язык описания структуры XML-документа (типы данных, обязательность) |
| SOAP-клиент | Программа, формирующая SOAP-запрос и отправляющая его серверу |
| SOAP-сервер | Программа, принимающая SOAP-запрос, обрабатывающая его и возвращающая SOAP-ответ |
1. Что такое SOAP и зачем он аналитику?
1.1. Аналогия: SOAP — курьерская служба с накладной
Представьте, что вам нужно отправить ценный груз (например, документы для сделки с недвижимостью). Вы не можете просто передать их лично — нужна курьерская служба:
| Элемент курьерской доставки | IT-аналог в SOAP |
|---|---|
| Вы (отправитель) | Клиентское приложение |
| Документы (груз) | Данные (XML-структура) |
| Накладная (Consignment Note) | SOAP-Envelope — упаковка с инструкциями |
| Отметка «секретно» на накладной | WS-Security заголовок |
| Подпись получателя (ACK) | SOAP-Response |
| Служба доставки | SOAP-протокол поверх HTTP/HTTPS |
| Курьер | HTTP POST-запрос |
| Адрес получателя | URL эндпоинта (SOAP endpoint) |
Ключевое отличие от REST-аналогии (официант в ресторане): в SOAP отправитель и получатель жёстко регламентируют формат накладной. Вы не можете написать «привет, вот документы» — только строго по шаблону: «отправитель, получатель, тип груза, страховка, подпись». Это минус (сложность), но и плюс (юридическая значимость, безопасность, транзакционность).
1.2. Зачем аналитику знать SOAP в 2026 году?
Казалось бы, REST победил — 90% новых API строятся на REST/JSON. Однако SOAP жив в корпоративных и государственных системах:
| Сфера | Почему SOAP | Примеры систем |
|---|---|---|
| Финансы (банки, страхование) | Требуются ACID-транзакции, юридическая значимость, WS-Security | SWIFT, ISO 20022, платёжные шлюзы |
| Госсектор | Законодательство требует формальных контрактов (WSDL — юридический документ) | Госуслуги, СМЭВ, ЕСИА |
| CRM / ERP | SAP, Oracle, 1С — все поддерживают SOAP-интеграцию «из коробки» | SAP PI/PO, 1С:Предприятие |
| Авиаперевозки / Отельный бизнес | Стандарты индустрии (OTA, IATA) — на SOAP/XML | Amadeus, Sabre |
| Телеком | Протоколы OSS/BSS | NetCracker, Ericsson |
| Enterprise Service Bus (ESB) | SOAP — родной формат для корпоративных шин | IBM Integration Bus, Oracle SOA Suite |
Реальность: Аналитик, который не умеет читать WSDL и понимать SOAP-сообщения, не сможет работать с интеграциями 1С, SAP, банковскими системами и госсектором. Это не «устаревшая технология» — это стандарт Enterprise-интеграции.
1.3. Задачи аналитика при работе с SOAP
| Задача | Что нужно делать |
|---|---|
| Чтение WSDL-контракта партнёра | Определить: какие операции есть, какие параметры, какой формат ответа, как аутентифицироваться |
| Описание SOAP-интеграции в требованиях | Написать: эндпоинт, SOAP Action, структуру запроса/ответа, WSDL-ссылку |
| Тестирование SOAP-сервиса | Через SoapUI/Postman — отправить запрос, прочитать ответ |
| Анализ ошибок интеграции | «SOAP-сервис вернул SOAP Fault» — нужно прочитать XML-ошибку |
| Проектирование SOAP-контракта | Составить WSDL-схему для нового сервиса (или описать требования для разработчика WSDL) |
2. Архитектура SOAP
2.1. Как выглядит SOAP-сообщение (анатомия)
SOAP-сообщение — это XML-документ строгой структуры. В нём ровно три части:
┌─────────────────────────────────────────────────────┐
│ SOAP-Envelope (корень) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ SOAP-Header (опционально) │ │
│ │ <wsse:Security> │ │
│ │ <wsse:UsernameToken> │ │
│ │ <wsse:Username>ivan</wsse:Username> │ │
│ │ <wsse:Password>***</wsse:Password> │ │
│ │ </wsse:UsernameToken> │ │
│ │ </wsse:Security> │ │
│ │ <wsa:To>http://example.com/TaskService</wsa:To>│ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ SOAP-Body (обязательно) │ │
│ │ <m:CreateTask> │ │
│ │ <m:title>Настроить CI/CD</m:title> │ │
│ │ <m:projectId>1</m:projectId> │ │
│ │ <m:priority>High</m:priority> │ │
│ │ </m:CreateTask> │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
| Часть | Обязательна? | Содержит |
|---|---|---|
| Envelope | ✅ Да | Корневой элемент. Указывает namespace SOAP (версия 1.1 или 1.2) |
| Header | ❌ Нет | Метаданные: аутентификация (WS-Security), маршрутизация (WS-Addressing), транзакция (WS-AtomicTransaction) |
| Body | ✅ Да | Данные запроса или ответа. Именно здесь — бизнес-содержимое |
2.2. Полный пример SOAP-запроса
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:task="http://www.example.com/taskmanager"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soap:Header>
<wsse:Security soap:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>service-account</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
YWJjZGVmZ2hpamtsbW5vcA==
</wsse:Password>
<wsse:Nonce>MTIzNDU2Nzg5MDEyMzQ1Ng==</wsse:Nonce>
<wsse:Created>2026-06-10T12:00:00Z</wsse:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<task:CreateTask>
<task:title>Настроить CI/CD pipeline</task:title>
<task:description>GitHub Actions для сборки</task:description>
<task:priority>High</task:priority>
<task:projectId>1</task:projectId>
<task:assigneeId>42</task:assigneeId>
<task:deadline>2026-07-01</task:deadline>
</task:CreateTask>
</soap:Body>
</soap:Envelope>
2.3. Полный пример SOAP-ответа (успех)
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:task="http://www.example.com/taskmanager">
<soap:Header/>
<soap:Body>
<task:CreateTaskResponse>
<task:taskId>42</task:taskId>
<task:status>To Do</task:status>
<task:createdAt>2026-06-10T12:00:15Z</task:createdAt>
</task:CreateTaskResponse>
</soap:Body>
</soap:Envelope>
2.4. SOAP Fault — стандартный формат ошибки
Когда что-то пошло не так, сервер возвращает SOAP Fault — строго структурированную ошибку:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Validation error</faultstring>
<faultactor>http://www.example.com/taskmanager</faultactor>
<detail>
<task:ValidationError xmlns:task="http://www.example.com/taskmanager">
<task:field>title</task:field>
<task:message>Title is required and must be 1-255 characters</task:message>
</task:ValidationError>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Структура Fault:
| Элемент | Описание | Пример |
|---|---|---|
<faultcode> |
Машинный код ошибки | soap:Client, soap:Server, soap:MustUnderstand, soap:VersionMismatch |
<faultstring> |
Человекочитаемое описание | Validation error |
<faultactor> |
URI источника ошибки (опционально) | http://example.com/taskmanager |
<detail> |
Детали ошибки (опционально — бизнес-специфичные) | <validationError>...</validationError> |
Стандартные faultcode:
| Код | Значение |
|---|---|
soap:VersionMismatch |
Несовпадение версий SOAP (сервер ждёт 1.2, а клиент шлёт 1.1) |
soap:MustUnderstand |
Заголовок с mustUnderstand="1" не был обработан сервером |
soap:Client |
Ошибка в запросе клиента (неверные данные, неполный XML) |
soap:Server |
Ошибка на стороне сервера (БД недоступна, внутреннее исключение) |
Для аналитика: SOAP Fault — это стандартизированная ошибка. В REST каждая компания придумывает свой формат ошибки. В SOAP — единый стандарт. Это огромное преимущество для автоматизации обработки ошибок.
2.5. SOAP-стили: Document vs RPC
У SOAP есть два стиля кодирования, которые аналитик должен различать:
| Характеристика | Document/Literal | RPC/Encoded |
|---|---|---|
| Структура Body | Содержит XML-документ (схема из WSDL) | Содержит название метода + параметры |
| Валидация | По XSD-схеме (строгая) | По правилам RPC (менее строгая) |
| Современность | ✅ Стандарт сегодня | ❌ Устарел (legacy) |
| Пример Body | <CreateTask><title>...</title></CreateTask> |
<createTask><param1 xsi:type="xsd:string">...</param1></createTask> |
| Когда встречается | Все современные SOAP-сервисы | Старые системы (SAP, legacy .NET) |
Золотое правило: Если в WSDL указан style="document" с use="literal" — это современный SOAP-сервис. Если style="rpc" — перед вами legacy-система. Большинство новых SOAP-интеграций используют Document/Literal.
3. WSDL — Web Services Description Language
3.1. Аналогия: WSDL — меню ресторана с технологическими картами
Представьте ресторан. REST — это меню с названиями блюд: «Паста Карбонара — 650р». Вы заказываете по названию, и вам приносят блюдо.
WSDL — это не просто меню, а меню + технологические карты для каждого блюда:
- «Блюдо: Паста Карбонара»
- «Ингредиенты: спагетти (200г), бекон (50г), яйцо (2шт), пармезан (30г)» — types
- «Шаг 1: отварить пасту. Шаг 2: обжарить бекон...» — operation (что делает повар)
- «Подача: на тарелке, посыпать пармезаном» — output (формат ответа)
- «Как передать заказ на кухню: записать на листок и передать повару» — binding (как вызвать)
3.2. Структура WSDL
WSDL-документ состоит из пяти основных секций:
┌──────────────────────────────────────────────────────────┐
│ WSDL Definitions │
│ │
│ 1. <types> ── Описание типов данных (XSD-схемы) │
│ 2. <message> ── Определение сообщений (вход/выход) │
│ 3. <portType> ── Интерфейс: какие операции есть │
│ 4. <binding> ── Привязка: SOAP протокол, transport │
│ 5. <service> ── Адрес (URL) сервиса │
└──────────────────────────────────────────────────────────┘
3.2.1. <types> — словарь данных
Здесь через XSD описываются все типы данных, которые используются в сообщениях:
<wsdl:types>
<xsd:schema targetNamespace="http://www.example.com/taskmanager">
<!-- Тип: запрос на создание задачи -->
<xsd:element name="CreateTaskRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<xsd:element name="description" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="priority" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="projectId" type="xsd:int" minOccurs="1" maxOccurs="1"/>
<xsd:element name="assigneeId" type="xsd:int" minOccurs="0" maxOccurs="1"/>
<xsd:element name="deadline" type="xsd:date" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- Тип: ответ при создании задачи -->
<xsd:element name="CreateTaskResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="taskId" type="xsd:int"/>
<xsd:element name="status" type="xsd:string"/>
<xsd:element name="createdAt" type="xsd:dateTime"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- Тип: ошибка валидации -->
<xsd:element name="ValidationError">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="field" type="xsd:string"/>
<xsd:element name="message" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
Важные XSD-атрибуты:
| Атрибут | Описание | Аналог в OpenAPI |
|---|---|---|
minOccurs="1" |
Поле обязательно | required: [field] |
minOccurs="0" |
Поле опционально | Поле без required |
maxOccurs="unbounded" |
Массив (повторяется много раз) | type: array |
type="xsd:int" |
Целое число | type: integer |
type="xsd:date" |
Дата (YYYY-MM-DD) | format: date |
type="xsd:dateTime" |
Дата и время | format: date-time |
type="xsd:string" |
Строка | type: string |
3.2.2. <message> — сообщения (вход и выход операции)
<wsdl:message name="CreateTaskInput">
<wsdl:part name="parameters" element="task:CreateTaskRequest"/>
</wsdl:message>
<wsdl:message name="CreateTaskOutput">
<wsdl:part name="parameters" element="task:CreateTaskResponse"/>
</wsdl:message>
<wsdl:message name="ValidationErrorFault">
<wsdl:part name="fault" element="task:ValidationError"/>
</wsdl:message>
Каждая операция имеет входное сообщение (Input), выходное (Output) и, опционально, сообщения об ошибках (Fault).
3.2.3. <portType> — интерфейс (что умеет сервис)
<wsdl:portType name="TaskServicePortType">
<wsdl:operation name="CreateTask">
<wsdl:input message="tns:CreateTaskInput"/>
<wsdl:output message="tns:CreateTaskOutput"/>
<wsdl:fault name="ValidationError" message="tns:ValidationErrorFault"/>
</wsdl:operation>
<wsdl:operation name="GetTaskById">
<wsdl:input message="tns:GetTaskByIdInput"/>
<wsdl:output message="tns:GetTaskByIdOutput"/>
<wsdl:fault name="NotFound" message="tns:NotFoundFault"/>
</wsdl:operation>
<wsdl:operation name="GetAllTasks">
<wsdl:input message="tns:GetAllTasksInput"/>
<wsdl:output message="tns:GetAllTasksOutput"/>
</wsdl:operation>
</wsdl:portType>
Операции бывают четырёх типов:
| Тип операции | Описание | Аналог в REST |
|---|---|---|
| Request-Response | Клиент отправляет запрос → Сервер возвращает ответ (самый частый) | Все REST-запросы |
| One-Way | Клиент отправляет запрос → Сервер ничего не возвращает | — (редко) |
| Notification | Сервер отправляет сообщение клиенту без запроса | Webhook / callback |
| Solicit-Response | Сервер отправляет запрос клиенту и ждёт ответ | Reverse-вызов |
На практике 99% SOAP-операций — Request-Response.
3.2.4. <binding> — как вызывать (протокол и транспорт)
<wsdl:binding name="TaskServiceSoapBinding" type="tns:TaskServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="CreateTask">
<soap:operation soapAction="http://www.example.com/taskmanager/CreateTask"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="ValidationError">
<soap:fault use="literal" name="ValidationError"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
Ключевые атрибуты binding:
| Атрибут | Описание | Варианты |
|---|---|---|
transport |
Транспортный протокол | soap/http (HTTP), soap/jms (JMS), soap/smtp (email) |
style |
Стиль кодирования | document (современный), rpc (устаревший) |
use |
Формат сериализации | literal (современный), encoded (устаревший) |
soapAction |
HTTP-заголовок SOAPAction (для HTTP-транспорта) | Уникальный URI для каждой операции |
Для аналитика:
soapAction— это строковый идентификатор операции, который передаётся в HTTP-заголовке. Он нужен, чтобы на одной URL-точке можно было разместить много операций, а сервер определял нужную по заголовку:POST /taskservice HTTP/1.1 Content-Type: text/xml; charset=utf-8 SOAPAction: "http://www.example.com/taskmanager/CreateTask"
3.2.5. <service> — где находится сервис (endpoint URL)
<wsdl:service name="TaskService">
<wsdl:port name="TaskServiceSoapPort" binding="tns:TaskServiceSoapBinding">
<soap:address location="https://api.example.com/soap/taskmanager/v1"/>
</wsdl:port>
<!-- Альтернативный binding (например, JMS) -->
<wsdl:port name="TaskServiceJmsPort" binding="tns:TaskServiceJmsBinding">
<soap:address location="jms://queue/TaskServiceQueue"/>
</wsdl:port>
</wsdl:service>
Один сервис — несколько портов (endpoint-ов):
- Основной: HTTP/SOAP (
https://...) - Для надёжной доставки: JMS (
jms://...) - Для тестов: другой URL
3.3. Сводная таблица: WSDL vs OpenAPI
| Аспект | WSDL (SOAP) | OpenAPI (REST) |
|---|---|---|
| Формат контракта | XML | YAML / JSON |
| Формат данных | XML (XSD) | JSON Schema |
| Транспорт | HTTP, JMS, SMTP, TCP (любой) | HTTP/HTTPS |
| Стиль | RPC / Document | Resource-based (CRUD) |
| Операции | Named: CreateTask, GetTaskById |
HTTP-методы + URL |
| Ошибки | SOAP Fault (стандартный XML) | HTTP status + произвольный JSON |
| Обязательность | Формальный контракт | Опционально (но рекомендуется) |
| Инструменты | SoapUI, IBM Rational, WSDL2Code | Swagger Editor, Postman, Redoc |
| Генерация кода | wsimport, svcutil, wsdl2java |
openapi-generator, swagger-codegen |
| Асинхронность | Через WS-Addressing + WS-ReliableMessaging | Через брокеры (Kafka, RabbitMQ) |
| Security | WS-Security (подпись, шифрование на уровне XML) | HTTPS + JWT / OAuth2 |
3.4. Как аналитику читать WSDL: пошаговая инструкция
Когда вы получили WSDL-файл от подрядчика или партнёра, действуйте так:
ШАГ 1: Найти <service> → URL эндпоинта
<soap:address location="https://api.example.com/soap/taskmanager/v1"/>
→ Куда отправлять запросы
ШАГ 2: Найти <portType> → список операций
<operation name="CreateTask"/>
<operation name="GetTaskById"/>
→ Что умеет сервис
ШАГ 3: Для каждой операции — найти <message> Input и Output
CreateTaskInput → ссылается на элемент CreateTaskRequest
CreateTaskOutput → ссылается на элемент CreateTaskResponse
→ Какие данные ожидает и возвращает операция
ШАГ 4: В <types> найти определения этих элементов (XSD)
CreateTaskRequest: {title (required), description (optional), ...}
CreateTaskResponse: {taskId, status, createdAt}
→ Точная структура данных
ШАГ 5: В <binding> найти soapAction
soapAction="http://www.example.com/taskmanager/CreateTask"
→ Какой заголовок SOAPAction указывать
ШАГ 6: Проверить fault-сообщения
Какие ошибки может вернуть сервис
Шпаргалка для быстрого анализа WSDL:
| Нужно узнать | Искать в WSDL |
|---|---|
| URL сервиса | //wsdl:service/wsdl:port/soap:address/@location |
| Список операций | //wsdl:portType/wsdl:operation/@name |
| Параметры операции | //wsdl:types//xsd:element[@name="<Operation>Request"] |
| Структура ответа | //wsdl:types//xsd:element[@name="<Operation>Response"] |
| Заголовок SOAPAction | //wsdl:binding/wsdl:operation/soap:operation/@soapAction |
| Формат ошибок | //wsdl:message для fault |
| Версия SOAP | //soap:binding/@transport (SOAP 1.1 или 1.2) |
4. SOAP vs REST — глубинное сравнение
4.1. Когда REST, а когда SOAP
┌──────────────────────────────────────────────────────────┐
│ Какой протокол выбрать для интеграции? │
│ │
│ 1. Есть жёсткие требования к ACID-транзакциям? │
│ Да ──→ SOAP + WS-AtomicTransaction │
│ │ │
│ Нет ─→ 2. Нужна юридическая значимость, │
│ подпись каждого сообщения? │
│ Да ──→ SOAP + WS-Security │
│ │ │
│ Нет ─→ 3. API будут использовать внешние │
│ разработчики (мобильные приложения)? │
│ Да ──→ REST (JSON легче, современнее) │
│ │ │
│ Нет ─→ 4. Интеграция legacy-систем │
│ (SAP, 1С, банк)? │
│ Да ──→ SOAP (скорее всего) │
│ Нет ─→ REST (по умолчанию) │
└──────────────────────────────────────────────────────────┘
4.2. Сравнительная таблица SOAP vs REST
| Характеристика | SOAP | REST |
|---|---|---|
| Протокол | Стандарт (W3C) | Архитектурный стиль (Fielding) |
| Формат данных | Только XML | JSON, XML, YAML, Protobuf (любой) |
| Транспорт | HTTP, JMS, SMTP, TCP, MQ | HTTP/HTTPS (почти всегда) |
| Контракт | WSDL (обязателен, формальный) | OpenAPI (опционален, рекомендуется) |
| Сложность | Высокая (много XML, namespaces, WS-*) | Низкая (URL + JSON) |
| Читаемость | Низкая (нужно парсить XML) | Высокая (JSON → читаем глазами) |
| ACID-транзакции | ✅ WS-AtomicTransaction | ❌ Нет (нужна Saga) |
| Безопасность на уровне сообщения | ✅ WS-Security (подпись, шифрование XML) | ❌ Только HTTPS (транспорт) |
| Надёжная доставка | ✅ WS-ReliableMessaging | ❌ Нужен брокер (Kafka/RabbitMQ) |
| Кэширование | Сложно (POST-запросы не кэшируются) | ✅ GET-запросы кэшируются |
| Производительность | Ниже (толстый XML-парсинг) | Выше (лёгкий JSON) |
| Размер сообщения | Большой (тело + envelope + namespaces) | Маленький (только данные) |
| Версионирование | Через namespace (v1, v2) |
Через URL или заголовки |
| Idempotency | Не встроена (нужна реализация) | GET/PUT/DELETE — идемпотентны |
| Генерация клиента | Из WSDL (строгий) | Из OpenAPI (опциональный) |
| Browser-friendly | ❌ Нет (нельзя вызвать из браузера) | ✅ Да (можно из fetch/ajax) |
| Когда использовать | Enterprise, финансы, госсектор, транзакции | Мобильные приложения, SPA, публичные API |
4.3. История из практики: почему банк выбрал SOAP
Кейс: Крупный банк интегрирует свою кредитную систему с внешним бюро кредитных историй (БКИ).
Требования:
- Юридическая значимость: каждое сообщение должно быть цифрово подписано
- Шифрование: персональные данные клиентов должны быть защищены на уровне XML-элементов, не только на уровне HTTPS
- ACID-транзакция: запрос кредитной истории + обновление скоринга — всё или ничего
- Надёжная доставка: сообщение должно быть доставлено ровно один раз (даже при сбоях)
Почему SOAP, а не REST:
| Требование | REST может? | SOAP может? |
|---|---|---|
| Цифровая подпись каждого XML-элемента | ❌ Нет (только HTTPS) | ✅ WS-Security XML Signature |
| Шифрование отдельных полей | ❌ Нет (только весь HTTPS) | ✅ WS-Security XML Encryption |
| Распределённая транзакция (2PC) | ❌ Нет (нужна Saga) | ✅ WS-AtomicTransaction |
| Exactly-once delivery | ❌ Нет (нужен брокер + идемпотентность) | ✅ WS-ReliableMessaging |
Вывод: Банк использует SOAP для интеграции с БКИ уже 15 лет. REST не能满足 требования безопасности и транзакционности на уровне сообщений.
5. WS-* стандарты — экосистема SOAP
SOAP — это не просто протокол, а целое семейство стандартов (WS-*), каждое из которых решает Enterprise-задачи:
5.1. Основные WS-* стандарты
| Стандарт | Задача | Аналог в мире REST / MQ |
|---|---|---|
| WS-Security | Подпись и шифрование SOAP-сообщений на уровне XML | HTTPS + JWT (но HTTPS не шифрует отдельные поля) |
| WS-AtomicTransaction (WS-AT) | Распределённые ACID-транзакции (2PC) между сервисами | Saga (но BASE, не ACID) |
| WS-ReliableMessaging (WS-RM) | Гарантированная доставка сообщений (exactly-once) | Kafka with idempotent producer |
| WS-Addressing | Маршрутизация сообщений (отправитель, получатель, reply-to, fault-to) | Correlation ID + заголовки |
| WS-Policy | Описание политик (какие security, какой transport) | OpenAPI securitySchemes |
| WS-MetadataExchange | Как получить WSDL сервиса через сам сервис | GET /openapi.json |
| WS-Trust | Выпуск и обновление токенов безопасности | OAuth2 / JWT |
| WS-Privacy | Политики конфиденциальности | — |
| WS-Coordination | Координация распределённых операций (основа для WS-AT) | — |
5.2. WS-Security подробнее
WS-Security (WSS) позволяет:
- Подписать SOAP-сообщение цифровой подписью (XML Signature)
- Зашифровать отдельные XML-элементы (XML Encryption)
- Прикрепить токен безопасности (Username Token, X.509, SAML, Kerberos)
<soap:Header>
<wsse:Security>
<!-- Токен: сертификат X.509 -->
<wsse:BinarySecurityToken
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
MIIDXTCCAkWgAwIBAgIJAPfU...
</wsse:BinarySecurityToken>
<!-- Цифровая подпись -->
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#body">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>Pdf83hY5...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>HW6Q2H8j...</ds:SignatureValue>
</ds:Signature>
</wsse:Security>
</soap:Header>
Для аналитика: Если в требованиях написано «обеспечить юридическую значимость электронного документооборота» — это означает WS-Security с цифровой подписью. REST эту задачу «из коробки» не решает.
5.3. WS-AtomicTransaction (WS-AT)
Позволяет выполнять распределённую ACID-транзакцию через несколько SOAP-сервисов:
Клиент Service A Service B
│ │ │
│── BeginTransaction ───────────→│ │
│ │── Register ───────────────→│
│ │ │
│── Operation 1 (CreateTask) ───→│ (локальный lock) │
│ │── Operation 2 (UpdateStock)→│ (локальный lock)
│ │ │
│── Commit ─────────────────────→│ │
│ │── Commit ─────────────────→│
│ │ │
│ │ (lock release) │
Аналог в REST: Нет. В REST приходится строить Saga с компенсациями.
6. SOAP-версии: 1.1 vs 1.2
Это важно, потому что SOAP 1.1 и 1.2 несовместимы:
| Аспект | SOAP 1.1 | SOAP 1.2 |
|---|---|---|
| Namespace | http://schemas.xmlsoap.org/soap/envelope/ |
http://www.w3.org/2003/05/soap-envelope |
| Транспортная нейтральность | Привязан к HTTP | Абстрагирован от транспорта |
| SOAPAction | Обязательный HTTP-заголовок | Может быть параметром application/soap+xml в Content-Type |
| Fault | faultcode, faultstring, faultactor, detail |
Code (Subcode), Reason, Detail, Role, Node |
| Content-Type | text/xml |
application/soap+xml |
| GET-запросы | Нет | Может использовать HTTP GET для идемпотентных запросов |
| Рекомендация W3C | Историческая | Текущая |
Как отличить SOAP 1.1 от 1.2 в WSDL:
<!-- SOAP 1.1 -->
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<soap:operation soapAction="..."/>
<!-- SOAP 1.2 -->
<soap12:binding transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" style="document"/>
<soap12:operation soapAction="..."/>
Для аналитика: При интеграции уточните версию SOAP. Если партнёр использует 1.1, а вы шлёте 1.2 — сервер вернёт SOAP Fault с
VersionMismatch.
7. Инструменты для работы с SOAP
7.1. SoapUI (основной инструмент)
SoapUI — это стандарт де-факто для тестирования SOAP-сервисов:
┌─────────────────────────────────────────────────────────────┐
│ SoapUI - TaskService │
│ │
│ 📂 TaskServiceProject │
│ 📁 CreateTask │
│ 📄 Request 1: create-task-valid.xml │
│ 📄 Request 2: create-task-empty-title.xml (fault) │
│ 📁 GetTaskById │
│ 📄 Request 1: get-task-42.xml │
│ 📄 TaskService.wsdl │
│ │
│ [▶] Run │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ <soap:Envelope ...> │ │
│ │ <soap:Header>...</soap:Header> │ │
│ │ <soap:Body> │ │
│ │ <CreateTask> │ │
│ │ <title>Test</title> │ │
│ │ </CreateTask> │ │
│ │ </soap:Body> │ │
│ │ </soap:Envelope> │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Response: 200 OK │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ <soap:Envelope ...> │ │
│ │ <soap:Body> │ │
│ │ <CreateTaskResponse> │ │
│ │ <taskId>42</taskId> │ │
│ │ ... │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Что умеет SoapUI:
- Импорт WSDL → автоматическая генерация SOAP-запросов
- Подстановка значений в XML
- Assertions (проверка ответа: статус, XPath, содержит подстроку)
- Mock-сервисы (эмуляция SOAP-сервера)
- Load testing
- Security testing (WS-Security)
7.2. Postman
Postman (начиная с версии 8) поддерживает SOAP:
- Вставка XML в тело запроса
- Добавление заголовка
SOAPAction - Content-Type:
text/xml(SOAP 1.1) илиapplication/soap+xml(SOAP 1.2) - Сборщик HTTP-заголовков
Ограничение: Postman не умеет парсить WSDL (не создаёт запросы автоматически). Для WSDL-навигации нужен SoapUI.
7.3. Генерация кода из WSDL
| Язык / Платформа | Инструмент |
|---|---|
| Java (JAX-WS) | wsimport -s . -p com.example.taskmanager TaskService.wsdl |
| Java (CXF) | wsdl2java -p com.example.taskmanager TaskService.wsdl |
| C# / .NET | svcutil TaskService.wsdl |
| PHP | SoapClient + WSDL (нативный) |
| Python | zeep — client = Client('TaskService.wsdl') |
| Node.js | soap — soap.createClient(url, callback) |
| Ruby | savon — client = Savon.client(wsdl: url) |
| 1С | WSСсылки — встроенная работа с WSDL |
Пример на Python с Zeep:
from zeep import Client
# Загружаем WSDL
wsdl_url = "https://api.example.com/soap/taskmanager/v1?wsdl"
client = Client(wsdl_url)
# Смотрим, какие операции доступны
print(client.service) # CreateTask, GetTaskById, GetAllTasks
# Вызываем операцию CreateTask
response = client.service.CreateTask(
title="Настроить CI/CD",
description="GitHub Actions",
priority="High",
projectId=1,
assigneeId=42,
deadline="2026-07-01"
)
print(f"Created task ID: {response['taskId']}, status: {response['status']}")
Для аналитика: Zeep и SoapClient берут на себя всю «магию» SOAP — формирование Envelope, namespaces, сериализацию XML. Вы просто вызываете методы Python-объекта. Но чтобы понять ошибку интеграции, нужно уметь читать «сырой» XML.
7.4. Отладка SOAP: снифферы
| Инструмент | Платформа | Особенность |
|---|---|---|
| Wireshark | Все | Перехват HTTP-трафика, фильтр http |
| Fiddler | Windows | HTTPS-прокси, просмотр SOAP-сообщений |
| Charles Proxy | macOS / Windows | Прокси с XML-форматированием |
| tcpdump | Linux | Консольный сниффер |
| Встроенные логи SoapUI | Все | Raw-логи запросов/ответов |
8. Типовые проблемы SOAP-интеграции и их диагностика
8.1. Таблица проблем
| Проблема | Симптом | Причина | Решение |
|---|---|---|---|
| VersionMismatch | SOAP Fault: VersionMismatch |
Клиент шлёт SOAP 1.1, сервер ждёт 1.2 (или наоборот) | Проверить namespace в Envelope и Content-Type |
| MustUnderstand | SOAP Fault: MustUnderstand |
Header с mustUnderstand="1" не обработан сервером |
Убрать неизвестные заголовки или договориться с сервером |
| Namespace mismatch | SOAP-элементы не распознаются | Несовпадение namespace в запросе и WSDL | Сверить targetNamespace в WSDL и xmlns в запросе |
| Отсутствует SOAPAction | HTTP 500 / SOAP Fault | Binding требует SOAPAction, клиент его не передал | Добавить HTTP-заголовок SOAPAction: "uri" |
| Невалидный XML | HTTP 400 / SOAP Fault | XML-структура не соответствует XSD | Проверить обязательность полей, порядок элементов, типы |
| SSL/TLS ошибка | Connection refused / Handshake failure | Сертификат сервера не доверенный или устарел | Установить сертификат УЦ, проверить цепочку доверия |
| Аутентификация | SOAP Fault: Access denied |
Неверный токен/пароль в WS-Security Header | Проверить UsernameToken, SAML, X.509 |
| Размер сообщения | HTTP 413 Payload Too Large | SOAP-сообщение превышает лимит сервера | Настроить max message size на сервере, сжать MTOM |
| Тайм-аут | HTTP 504 / Connection timeout | Сервер не отвечает в течение timeout | Увеличить тайм-аут, оптимизировать сервер |
| WSDL недоступен | Ошибка при инициализации клиента | WSDL URL возвращает 404 или недоступен | Кэшировать WSDL локально, проверить URL |
8.2. Пример диагностики ошибки
Ситуация: Интеграция с 1С падает. 1С возвращает SOAP Fault.
Шаг 1. Читаем сырой HTTP-ответ:
HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Ошибка СКД: Поле не найдено 'DocumentNumber'</faultstring>
<detail>
<error xmlns="http://v8.1c.ru/8.1/data/enterprise/">
<code>SKD-0042</code>
<description>Компоновщик настроек: поле "DocumentNumber" не найдено в доступных полях</description>
</error>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Шаг 2. Анализируем:
faultcode: soap:Client— ошибка в запросе (наша вина)faultstring: "Поле не найдено 'DocumentNumber'"— 1С не может найти поле- Скорее всего, в XML-запросе нет поля
DocumentNumber, а 1С его ожидает
Шаг 3. Решение:
- Проверить WSDL: в XSD-схеме операции есть
DocumentNumber? - Добавить
DocumentNumberв SOAP-запрос - Или: в схеме 1С это поле опционально (
minOccurs="0"), но 1С всё равно его требует — уточнить у вендора
9. Практический пример: SOAP-интеграция с 1С
9.1. Контекст
1С:Предприятие — наиболее частый партнёр по SOAP-интеграции в российском Enterprise. 1С публикует свои «веб-сервисы» (WebServices) через HTTP-сервер (Apache / IIS) и предоставляет WSDL.
Типовые точки интеграции с 1С:
- Выгрузка заказов из Интернет-магазина → 1С
- Загрузка остатков товаров из 1С → Сайт
- Синхронизация контрагентов (CRM ↔ 1С)
- Обмен документами (счета, накладные, акты)
9.2. Пример SOAP-запроса к 1С
Операция: GetStockRemains — получить остатки товаров на складе
SOAP-запрос:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:c1="http://www.1c.ru/stock">
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>exchange_user</wsse:Username>
<wsse:Password>Password123</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<c1:GetStockRemains>
<c1:warehouseId>WH-001</c1:warehouseId>
<c1:dateFrom>2026-06-01</c1:dateFrom>
<c1:dateTo>2026-06-10</c1:dateTo>
</c1:GetStockRemains>
</soap:Body>
</soap:Envelope>
SOAP-ответ (успех):
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:c1="http://www.1c.ru/stock">
<soap:Body>
<c1:GetStockRemainsResponse>
<c1:items>
<c1:item>
<c1:productId>PR-001</c1:productId>
<c1:productName>Стул офисный</c1:productName>
<c1:quantity>150</c1:quantity>
<c1:price>12500.00</c1:price>
</c1:item>
<c1:item>
<c1:productId>PR-002</c1:productId>
<c1:productName>Стол рабочий</c1:productName>
<c1:quantity>42</c1:quantity>
<c1:price>24500.00</c1:price>
</c1:item>
</c1:items>
</c1:GetStockRemainsResponse>
</soap:Body>
</soap:Envelope>
9.3. Рекомендации аналитику для интеграции с 1С
| Совет | Почему |
|---|---|
Всегда запрашивайте WSDL (его можно получить по адресу http://1c-server/база/ws/ИмяВебСервиса?wsdl) |
Без WSDL вы не узнаете точную структуру запроса |
| Используйте Basic Auth или WS-Security UsernameToken | 1С аутентифицирует по пользователю базы |
| Проверяйте версию SOAP (1С 8.3 поддерживает 1.1 и 1.2) | Уточните у администратора 1С |
| Используйте http-заголовок SOAPAction (он проставляется из WSDL) | Без него 1С может не распознать операцию |
| Учитывайте кодировку | 1С работает в UTF-8 для веб-сервисов |
| Проверяйте namespace 1С | Типичный: http://www.1c.ru/8.1/data/enterprise/ или свой |
| Будьте готовы к SOAP Fault | 1С возвращает ошибки в русскоязычном faultstring; «Ошибка СКД», «Ошибка вызова контекста» |
| Тестируйте в SoapUI перед интеграцией | SoapUI правильно формирует namespace и заголовки |
10. SOAP vs gRPC — ещё один конкурент
Хотя gRPC редко встречается в Enterprise-интеграциях (банки, госсектор), полезно понимать позиционирование:
| Характеристика | SOAP | gRPC | REST |
|---|---|---|---|
| Transport | HTTP 1.1 | HTTP 2 | HTTP 1.1/2 |
| Format | XML (текстовый) | Protobuf (бинарный) | JSON (текстовый) |
| Schema | WSDL | .proto (Protocol Buffers) |
OpenAPI |
| Streaming | ❌ Нет | ✅ Bidirectional streaming | ❌ Нет (кроме WebSocket) |
| Browser | ❌ Нет | ❌ Нет (нужен gRPC-Web) | ✅ Да |
| Code generation | Из WSDL | Из .proto (генерация обязательна) |
Из OpenAPI (опциональна) |
| Human readable | ❌ Нет (тяжелый XML) | ❌ Нет (бинарный protobuf) | ✅ Да (JSON) |
| Enterprise (Security, TX) | ✅ WS-* (сильная) | ⚠️ Слабее (TLS + JWT) | ❌ Нет |
| Где используется | Enterprise, банки, 1С, SAP | Микросервисы (Google, Netflix) | Публичные API, мобильные |
Для аналитика: Если вам говорят «у нас тут SOAP-интеграция с банком» — это норма. Если вам говорят «давайте на gRPC сделаем интеграцию с 1С» — это странно. gRPC — технология для высоконагруженных микросервисов, а не для Enterprise-интеграции с legacy.
11. Как аналитику описывать SOAP-интеграцию в требованиях
11.1. Шаблон описания SOAP-интеграции
### Интеграция: Загрузка заказов из Интернет-магазина в 1С
**Тип:** SOAP-веб-сервис (синхронный)
**Направление:** Интернет-магазин → 1С:Предприятие (выгрузка заказов)
#### Параметры подключения:
- WSDL-URL: http://1c-server/trade/ws/OrderExchange?wsdl
- Адрес эндпоинта: http://1c-server/trade/ws/OrderExchange
- Версия SOAP: 1.1
- Content-Type: text/xml; charset=utf-8
- HTTP-метод: POST
- SOAPAction: "http://www.1c.ru/trade/OrderExchange#ImportOrders"
- Аутентификация: Basic Auth (логин/пароль пользователя 1С)
#### Операции:
| Операция | Назначение | Входные данные | Выходные данные |
|----------|------------|----------------|-----------------|
| ImportOrders | Импорт заказов | OrderListRequest | OrderListResponse |
| GetOrderStatus | Проверка статуса | OrderStatusRequest | OrderStatusResponse |
#### Структура ImportOrdersRequest:
```xml
<soap:Envelope>
<soap:Header>
<!-- UsernameToken: логин/пароль -->
</soap:Header>
<soap:Body>
<ImportOrders>
<orders>
<order>
<orderNumber>string</orderNumber>
<orderDate>dateTime</orderDate>
<customerId>string</customerId>
<items>...</items>
<totalAmount>decimal</totalAmount>
</order>
</orders>
</ImportOrders>
</soap:Body>
</soap:Envelope>
Ошибки:
| Код ошибки (faultcode) | Описание | Действие |
|---|---|---|
| soap:Client | Неверный XML, обязательные поля отсутствуют | Исправить запрос |
| soap:Server | Внутренняя ошибка 1С | Повторить через 1 минуту |
| tns:AuthError | Неверный логин/пароль | Проверить учётные данные |
Требования к отказоустойчивости:
| NFR | Значение |
|---|---|
| Тайм-аут запроса | 30 секунд |
| Retry policy | 3 попытки, exponential backoff (1, 5, 15 сек) |
| Idempotency | По номеру заказа (orderNumber) — повторная отправка не создаёт дубликат |
| Мониторинг | Логировать все SOAP-запросы и ответы, алерт при SOAP Fault |
### 11.2. Чек-лист для аналитика при проектировании SOAP-интеграции
| № | Проверка | ⚠️ |
|:-:|----------|:--:|
| 1 | Получен WSDL от владельца сервиса | |
| 2 | Определена версия SOAP (1.1 или 1.2) | |
| 3 | Определён стиль (Document/Literal, RPC/Encoded) | |
| 4 | Определён transport (HTTP или JMS/SMTP) | |
| 5 | Определены все операции (portType → operation) | |
| 6 | Для каждой операции: Input, Output, Fault — структура данных | |
| 7 | Определены обязательные поля (minOccurs="1") | |
| 8 | Определены типы данных (string, int, date, decimal, enum) | |
| 9 | Определён SOAPAction для каждой операции | |
| 10 | Определён метод аутентификации (Basic, WS-Security, SAML) | |
| 11 | Определён формат ошибок (какие faultcode возможны) | |
| 12 | Установлен timeout на запрос | |
| 13 | Установлен retry policy | |
| 14 | Проверена идемпотентность (ключ для dedup) | |
| 15 | Создан тестовый запрос в SoapUI | |
---
## Вопросы для самопроверки
### Базовый уровень
1. **Что такое SOAP?** Чем SOAP-Envelope отличается от простого XML-документа?
2. **Назовите обязательные элементы SOAP-сообщения.** Что будет, если отправить SOAP-запрос без Body?
3. **Что такое WSDL?** Какие пять секций входят в WSDL-документ?
4. **Чем SOAP отличается от REST** по формату данных, транспорту, обязательности контракта?
5. **Что такое SOAP Fault?** Перечислите четыре стандартных faultcode и их значение.
### Продвинутый уровень
6. **WS-Security:** Почему в банковской интеграции используют WS-Security, а не просто HTTPS? Что даёт XML-шифрование и XML-подпись поверх транспортного шифрования?
7. **Document vs RPC:** Вам дали WSDL со `style="rpc" use="encoded"`. Что это значит для аналитика? Почему это legacy?
8. **SOAP 1.1 vs 1.2:** Как по WSDL отличить версию SOAP? Что произойдёт, если клиент отправит SOAP 1.2 запрос на сервер, ожидающий 1.1?
9. **WSDL для аналитика:** Откройте любой WSDL (реальный из интернета, например `http://www.dneonline.com/calculator.asmx?wsdl`). Найдите: service endpoint, portType, operation, message, types. Опишите структуру одной операции.
10. **Выбор протокола:** Вам нужно интегрировать Интернет-магазин (на Modern Java + React) с банковской платёжной системой. Какие критерии определят выбор между REST и SOAP?
---
## Практическое задание
### Задание 1. Анализ WSDL (3 балла)
Дан WSDL-контракт сервиса управления задачами (адаптированный реальный пример):
```xml
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.com/taskmanager"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/taskmanager">
<wsdl:types>
<xsd:schema targetNamespace="http://www.example.com/taskmanager">
<xsd:element name="CreateTaskRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1"/>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element name="priority" type="xsd:string" minOccurs="0"/>
<xsd:element name="projectId" type="xsd:int" minOccurs="1"/>
<xsd:element name="assigneeId" type="xsd:int" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="CreateTaskResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="taskId" type="xsd:int"/>
<xsd:element name="status" type="xsd:string"/>
<xsd:element name="createdAt" type="xsd:dateTime"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="CreateTaskInput">
<wsdl:part name="parameters" element="tns:CreateTaskRequest"/>
</wsdl:message>
<wsdl:message name="CreateTaskOutput">
<wsdl:part name="parameters" element="tns:CreateTaskResponse"/>
</wsdl:message>
<wsdl:portType name="TaskServicePortType">
<wsdl:operation name="CreateTask">
<wsdl:input message="tns:CreateTaskInput"/>
<wsdl:output message="tns:CreateTaskOutput"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TaskServiceSoapBinding" type="tns:TaskServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="CreateTask">
<soap:operation soapAction="http://www.example.com/taskmanager/CreateTask"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TaskService">
<wsdl:port name="TaskServiceSoapPort" binding="tns:TaskServiceSoapBinding">
<soap:address location="https://api.example.com/soap/taskmanager/v1"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Ответьте на вопросы:
- (0,5 балла) Какая версия SOAP используется (1.1 или 1.2)? Как вы это определили?
- (0,5 балла) Какой URL эндпоинта и какой SOAPAction для операции CreateTask?
- (1 балл) Опишите структуру CreateTaskRequest: какие поля обязательны, какие опциональны, каких типов?
- (0,5 балла) Какая операция описана в portType? Как называется интерфейс?
- (0,5 балла) Какой стиль и use используется в binding? (Document/Literal или RPC/Encoded?)
Задание 2. Напишите SOAP-запрос и ответ (2 балла)
На основе WSDL из Задания 1:
2.1. (1 балл) Напишите валидный SOAP 1.1 запрос для создания задачи:
- title: "Исправить баг авторизации"
- description: "Пользователь не может войти через Google"
- priority: "Critical"
- projectId: 5
- (assigneeId не указываем — опционально)
2.2. (1 балл) Предположите, какой будет SOAP-ответ (в формате XML), если сервер успешно создал задачу с taskId=128, статусом "To Do" и текущим временем.
Задание 3. SOAP vs REST (2 балла)
Для каждого сценария выберите протокол (SOAP или REST) и обоснуйте:
| № | Сценарий | Протокол? | Почему? |
|---|---|---|---|
| 1 | Мобильное приложение для просмотра погоды | ||
| 2 | Интеграция банк-банк для межбанковского перевода (юридически значимый) | ||
| 3 | Микросервисная архитектура стартапа (20 микросервисов, React-фронтенд) | ||
| 4 | Выгрузка документов из CRM в 1С:Бухгалтерия | ||
| 5 | Публичное API для разработчиков (соцсеть, мессенджер) |
Задание 4. Анализ ошибки SOAP-интеграции (3 балла)
Дан реальный кейс. Есть SOAP-сервис расчёта стоимости доставки. Клиент отправляет запрос и получает ошибку:
Запрос клиента:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:del="http://delivery.example.com/calc">
<soap:Body>
<del:CalculateDeliveryCost>
<del:fromIndex>101000</del:fromIndex>
<del:toIndex>190000</del:toIndex>
<del:weight>5.5</del:weight>
</del:CalculateDeliveryCost>
</soap:Body>
</soap:Envelope>
Ответ сервера:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:VersionMismatch</faultcode>
<faultstring>Transport binding found for SOAP 1.1, but message is SOAP 1.2</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Вопросы:
4.1. (1 балл) В чём причина ошибки? (Какая версия SOAP у клиента, какая у сервера?) 4.2. (1 балл) Как исправить запрос клиента? 4.3. (1 балл) Если бы вы были аналитиком, описывающим эту интеграцию, какие два параметра вы бы обязательно зафиксировали в требованиях к подключению, чтобы избежать этой ошибки?
Критерии оценки
| Задание | Баллы |
|---|---|
| Задание 1: Анализ WSDL | 3 |
| Задание 2: Написать SOAP-запрос и ответ | 2 |
| Задание 3: SOAP vs REST (выбор протокола) | 2 |
| Задание 4: Анализ ошибки SOAP-интеграции | 3 |
| Итого | 10 |
Справочные материалы
SOAP 1.1 Namespace
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
Content-Type: text/xml; charset=utf-8
HTTP-заголовок SOAPAction: обязателен
SOAP 1.2 Namespace
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
Content-Type: application/soap+xml; charset=utf-8
HTTP-заголовок SOAPAction: опционален
WSDL Namespace
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
WS-Security Namespace
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
Инструменты
| Инструмент | Назначение | Сайт |
|---|---|---|
| SoapUI | Тестирование SOAP-сервисов | https://www.soapui.org/ |
| Postman | HTTP-клиент (SOAP поддерживается) | https://www.postman.com/ |
| Wireshark | Сниффер трафика | https://www.wireshark.org/ |
| Zeep (Python) | SOAP-клиент для Python | https://docs.python-zeep.org/ |
| wsimport (Java) | Генерация Java-классов из WSDL | Встроен в JDK (bin/wsimport) |
| Online WSDL Viewer | Визуализация WSDL | https://www.wsdl-analyzer.com/ |