Перейти к содержимому

Что такое SOAP

SOAP — XML-протокол обмена сообщениями в распределённых системах (банки, страховые, госсектор). Сообщение строгой структуры: Envelope (обязательный), Header (метаданные: аутентификация, транзакции), Body (основное сообщение), Fault (ошибки). Контракт — WSDL (обязательный), описывает операции, параметры, типы, транспорт, позволяет генерировать клиентский код автоматически. Транспорты: HTTP, SMTP, JMS, TCP. Стандарты: WS-Security (подпись, шифрование, аутентификация), WS-AtomicTransaction (распределённые транзакции ACID), WS-ReliableMessaging (гарантированная доставка, упорядочивание). Преимущества: формальный контракт, строгая типизация, безопасность и транзакции «из коробки», независимость от транспорта. Недостатки: сложность, многословность (XML в 10-20 раз больше JSON), медленнее, плохое кеширование (почти всегда POST). Выбор: SOAP для корпоративных систем (безопасность, транзакции, надёжность), REST для публичных API, микросервисов, мобильных приложений.

Введение: Тяжеловес корпоративных интеграций

В мире API есть два совершенно разных мира. Один — REST. Лёгкий, гибкий, интуитивный. Его любят разработчики мобильных приложений и веб-сервисов. Другой — SOAP. Формальный, строгий, многословный. Его выбирают банки, страховые компании, государственные системы.

SOAP (Simple Object Access Protocol) — это протокол обмена структурированными сообщениями в распределённых системах. Несмотря на слово “Simple” в названии, SOAP — один из самых сложных и многословных протоколов в мире API.

SOAP был создан в конце 1990-х годов как стандарт для взаимодействия между приложениями, написанными на разных языках и работающими на разных платформах. Он неразрывно связан с XML и использует его как формат сообщений.

Если REST — это “почтовое отделение” (вы отправляете запрос и получаете ответ), то SOAP — это “нотариальная контора” (каждое сообщение должно быть оформлено по строгим правилам, заверено, проверено и доставлено с гарантиями). SOAP обеспечивает надёжность, безопасность и формальные контракты, но ценой сложности и производительности.

История и контекст

SOAP был создан в 1998 году компаниями Microsoft, IBM, Lotus и UserLand. В 2000 году он был передан в W3C и стал стандартом. В 2000-х годах SOAP был доминирующим протоколом для веб-сервисов в корпоративной среде.

Сегодня SOAP всё ещё широко используется, особенно в:

  • Банковских системах
  • Платёжных шлюзах
  • Страховых компаниях
  • Государственных информационных системах
  • Системах, где важны строгие контракты и безопасность

Однако для новых проектов, особенно публичных API, чаще выбирают REST, GraphQL или gRPC.

Основные понятия SOAP

SOAP сообщение

SOAP сообщение — это XML документ строгой структуры.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <!-- Необязательная часть. Аутентификация, транзакции, маршрутизация -->
    </soap:Header>
    <soap:Body>
        <!-- Обязательная часть. Основное сообщение -->
        <GetUser>
            <UserId>123</UserId>
        </GetUser>
    </soap:Body>
    <soap:Fault>
        <!-- Ошибки -->
    </soap:Fault>
</soap:Envelope>

Структура SOAP сообщения

КомпонентОбязательностьНазначение
EnvelopeОбязательныйКорневой элемент, определяет XML как SOAP сообщение
HeaderНеобязательныйМетаданные: аутентификация, транзакции, маршрутизация
BodyОбязательныйОсновное содержимое запроса или ответа
FaultНеобязательныйИнформация об ошибках

Пример SOAP запроса и ответа

Запрос: получить пользователя

POST /UserService HTTP/1.1
Host: api.example.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://example.com/UserService/GetUser"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:user="http://example.com/user">
    
    <soap:Header>
        <user:Auth>
            <user:ApiKey>abc123xyz</user:ApiKey>
        </user:Auth>
    </soap:Header>
    
    <soap:Body>
        <user:GetUserRequest>
            <user:UserId>123</user:UserId>
        </user:GetUserRequest>
    </soap:Body>
    
</soap:Envelope>

Ответ

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:user="http://example.com/user">
    
    <soap:Body>
        <user:GetUserResponse>
            <user:UserId>123</user:UserId>
            <user:Name>Иван Петров</user:Name>
            <user:Email>ivan@example.com</user:Email>
            <user:CreatedAt>2024-01-15T10:30:00Z</user:CreatedAt>
        </user:GetUserResponse>
    </soap:Body>
    
</soap:Envelope>

WSDL: Контракт SOAP сервиса

WSDL (Web Services Description Language) — это XML документ, который описывает, как вызывать SOAP сервис. Это “контракт” между клиентом и сервером.

WSDL описывает:

  • Какие операции доступны
  • Какие параметры принимает каждая операция
  • Какой формат ответа
  • Какой транспорт используется (обычно HTTP)
  • Где находится сервис (URL)

Пример фрагмента WSDL

<definitions targetNamespace="http://example.com/user">
    
    <!-- Типы данных -->
    <types>
        <xsd:schema>
            <xsd:element name="GetUserRequest">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="UserId" type="xsd:int"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            
            <xsd:element name="GetUserResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="UserId" type="xsd:int"/>
                        <xsd:element name="Name" type="xsd:string"/>
                        <xsd:element name="Email" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:schema>
    </types>
    
    <!-- Сообщения -->
    <message name="GetUserRequest">
        <part name="parameters" element="tns:GetUserRequest"/>
    </message>
    <message name="GetUserResponse">
        <part name="parameters" element="tns:GetUserResponse"/>
    </message>
    
    <!-- Операции -->
    <portType name="UserPort">
        <operation name="GetUser">
            <input message="tns:GetUserRequest"/>
            <output message="tns:GetUserResponse"/>
        </operation>
    </portType>
    
    <!-- Привязка к протоколу -->
    <binding name="UserBinding" type="tns:UserPort">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="GetUser">
            <soap:operation soapAction="http://example.com/UserService/GetUser"/>
            <input><soap:body use="literal"/></input>
            <output><soap:body use="literal"/></output>
        </operation>
    </binding>
    
    <!-- Адрес сервиса -->
    <service name="UserService">
        <port name="UserPort" binding="tns:UserBinding">
            <soap:address location="https://api.example.com/UserService"/>
        </port>
    </service>
    
</definitions>

Что даёт WSDL

ПреимуществоОбъяснение
Автоматическая генерация кодаИнструменты могут создать клиентский код по WSDL
СамодокументируемостьWSDL описывает всё, что нужно знать для вызова
Проверка контрактаМожно валидировать сообщения против схемы
СтандартизацияЕдиный формат описания сервисов

Транспортные протоколы SOAP

SOAP не привязан к HTTP. Он может работать через разные протоколы.

ПротоколОписаниеКогда используется
HTTP/HTTPSСамый распространённыйВеб-сервисы
SMTPЭлектронная почтаАсинхронные системы
JMSJava Message ServiceКорпоративные очереди
TCPПрямое сокетное соединениеВысокая производительность

SOAP и стили сообщений

RPC/Encoded (устаревший)

Сообщение кодирует вызов процедуры с типами данных.

<soap:Body>
    <GetUser>
        <UserId xsi:type="xsd:int">123</UserId>
    </GetUser>
</soap:Body>

RPC/Literal

Вызов процедуры без указания типов (типы в WSDL).

<soap:Body>
    <GetUser>
        <UserId>123</UserId>
    </GetUser>
</soap:Body>

Document/Literal (самый распространённый)

Документо-ориентированный стиль.

<soap:Body>
    <GetUserRequest>
        <UserId>123</UserId>
    </GetUserRequest>
</soap:Body>

Document/Literal Wrapped

Вариант Document/Literal с обёрткой.

<soap:Body>
    <GetUser>
        <UserId>123</UserId>
    </GetUser>
</soap:Body>

Сегодня стандарт — Document/Literal Wrapped.

SOAP и безопасность (WS-Security)

SOAP имеет встроенные механизмы безопасности, которых нет в REST.

Пример SOAP сообщения с подписью

<soap:Header>
    <wsse:Security>
        <!-- Подпись сообщения -->
        <ds:Signature>
            <ds:SignedInfo>...</ds:SignedInfo>
            <ds:SignatureValue>...</ds:SignatureValue>
        </ds:Signature>
        
        <!-- Шифрование -->
        <xenc:EncryptedKey>...</xenc:EncryptedKey>
        
        <!-- Токен пользователя -->
        <wsse:UsernameToken>
            <wsse:Username>ivan</wsse:Username>
            <wsse:Password>***</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soap:Header>

Возможности WS-Security

ВозможностьОписание
АутентификацияUsername Token, X.509, Kerberos, SAML
Подпись сообщенийЦелостность и неотказуемость
ШифрованиеКонфиденциальность
ТаймстемпыЗащита от replay-атак

SOAP и транзакции (WS-AtomicTransaction)

SOAP поддерживает распределённые транзакции через WS-AtomicTransaction.

<soap:Header>
    <wsat:AtomicTransaction>
        <wsat:TransactionID>uuid-123-456</wsat:TransactionID>
    </wsat:AtomicTransaction>
</soap:Header>

Когда нужно: Банковские переводы, бронирование авиабилетов, системы, требующие ACID.

SOAP и надёжность (WS-ReliableMessaging)

Гарантирует доставку сообщений даже при сбоях сети.

<soap:Header>
    <wsrm:Sequence>
        <wsrm:Identifier>uuid-123</wsrm:Identifier>
        <wsrm:MessageNumber>1</wsrm:MessageNumber>
    </wsrm:Sequence>
</soap:Header>

Возможности:

  • Подтверждение получения
  • Повторная отправка
  • Упорядочивание сообщений
  • Устранение дубликатов

SOAP в языках программирования

C# (.NET)

// Создание клиента из WSDL (Add Service Reference)
var client = new UserServiceClient();

// Вызов метода
var response = client.GetUser(new GetUserRequest { UserId = 123 });

Console.WriteLine($"User: {response.Name}, Email: {response.Email}");

Java (JAX-WS)

// Генерация клиента из WSDL
URL url = new URL("https://api.example.com/UserService?wsdl");
QName qname = new QName("http://example.com/user", "UserService");
Service service = Service.create(url, qname);
UserPort port = service.getPort(UserPort.class);

// Вызов метода
GetUserResponse response = port.getUser(123);
System.out.println("User: " + response.getName());

Python (Zeep)

from zeep import Client

client = Client('https://api.example.com/UserService?wsdl')
response = client.service.GetUser(UserId=123)

print(f"User: {response.Name}, Email: {response.Email}")

Преимущества SOAP

ПреимуществоОбъяснение
Формальный контракт (WSDL)Клиенты могут генерировать код автоматически
Строгая типизацияМеньше ошибок, лучше валидация
Безопасность (WS-Security)Подпись, шифрование, токены “из коробки”
Транзакции (WS-AtomicTransaction)Поддержка ACID распределённых транзакций
Надёжность (WS-ReliableMessaging)Гарантированная доставка
Независимость от транспортаРаботает через HTTP, SMTP, JMS, TCP
Поддержка асинхронных операцийCallback, long-running operations

Недостатки SOAP

НедостатокОбъяснение
СложностьWSDL, XML, пространства имён, заголовки — крутая кривая обучения
Многословность (Verbosity)Сообщения в 10-20 раз больше, чем JSON в REST
МедленнееПарсинг XML, валидация, обработка заголовков
Плохая кешируемостьPOST почти всегда, GET редко
Сложное тестированиеНужны специальные инструменты (SoapUI)
Неудобно в браузереНельзя просто открыть в браузере
Избыточен для простых задачДля простых CRUD операций — слишком тяжело

SOAP vs REST: Краткое сравнение

ХарактеристикаSOAPREST
ФорматXML (только)JSON, XML, HTML, текст
ПротоколHTTP, SMTP, JMS, TCPHTTP/HTTPS
КонтрактWSDL (обязательный)OpenAPI (опциональный)
СостояниеМожет быть statefulStateless
БезопасностьWS-SecurityHTTPS + OAuth/JWT
ТранзакцииWS-AtomicTransactionНет (нужен компенсирующий механизм)
НадёжностьWS-ReliableMessagingНет (нужно реализовывать поверх)
КешированиеПлохоеХорошее (HTTP кеш)
СложностьВысокаяНизкая
ПроизводительностьНизкая (XML)Высокая (JSON)

Когда выбирать SOAP

SOAP подходит, если:

СценарийПочему
Корпоративные системы (банки, страховые)Требуют строгих контрактов, безопасности, транзакций
Государственные системыЧасто требуют SOAP по стандарту
Системы с длительными операциямиАсинхронные вызовы, callbacks
Требуется WS-SecurityПодпись, шифрование, сложная аутентификация
Разные транспортыНужно работать через SMTP или JMS
Существующая инфраструктураВсё уже построено на SOAP
Автоматическая генерация клиентовМного разных клиентов на разных языках

SOAP не подходит, если:

СценарийПочему
Публичный API для веб-приложенийREST проще, быстрее, удобнее
Мобильные приложенияТяжёлый XML и многословность на медленных сетях
МикросервисыSOAP слишком тяжёлый и медленный
Быстрое прототипированиеСлишком много формальностей
Кеширование важноSOAP почти всегда POST
Команда не знает XMLКрутая кривая обучения

Частые ошибки

Ошибка 1: SOAP для простого CRUD API

Создание SOAP сервиса для простого списка задач.

Как исправить: REST с JSON.

Ошибка 2: Игнорирование WSDL

Вызов SOAP сервиса без использования WSDL, ручное формирование XML.

Как исправить: Использовать инструменты для генерации клиента из WSDL.

Ошибка 3: Неправильный стиль сообщений

Использование RPC/Encoded, который плохо поддерживается современными инструментами.

Как исправить: Document/Literal Wrapped.

Ошибка 4: SOAP без безопасности

Использование SOAP без WS-Security, только HTTPS. Потеря подписи и шифрования на уровне сообщений.

Как исправить: Если безопасность критична, используйте WS-Security.

Ошибка 5: Синхронные вызовы для длительных операций

Запрос, который обрабатывается минутами, через синхронный SOAP вызов.

Как исправитить: Использовать асинхронный паттерн (два запроса: старт и получение результата).

Резюме для системного аналитика

  1. SOAP (Simple Object Access Protocol) — протокол обмена структурированными сообщениями на основе XML. Несмотря на название, он далеко не простой.

  2. SOAP сообщение состоит из Envelope (конверт), Header (необязательные метаданные), Body (основное сообщение), Fault (ошибки).

  3. WSDL (Web Services Description Language) — контракт SOAP сервиса. Описывает операции, параметры, типы данных, транспорт. Позволяет генерировать клиентский код автоматически.

  4. Стандарты SOAP: WS-Security (безопасность), WS-AtomicTransaction (транзакции), WS-ReliableMessaging (надёжность). Этого нет в REST.

  5. SOAP сложен, но мощен. Строгая типизация, формальные контракты, встроенная безопасность и транзакции — за это его любят в корпоративной среде.

  6. SOAP не для всех. Для публичных API, мобильных приложений, микросервисов REST подходит больше. SOAP — для банков, страховых, государства.

Проверка знаний

Вопрос 1 из 4
Что такое SOAP?
Какой формат данных является базовым для SOAP?
Что обычно описывает контракт SOAP-сервиса?
Почему слово «Simple» в названии SOAP обманчиво?

Вопросы, где были ошибки