SOAP(Simple Object Access Protocol)
0. 들어가면서
조만간 말로만 듣던 SOAP(Simple Object Access Protocol)
기반의 통신을 하는 어플리케이션과 협력할 것 같습니다.
단순하게 생각한 것과 달리 굉장히 복잡한 프로토콜이어서 놀랐습니다.
심플(simple)하지 않은 SOAP
에 대해 정리하였습니다.
1. SOAP(Simple Object Access Protocol)
SOAP
은 일반적으로 널리 알려진 HTTP, HTTPS, SMTP 등을 통해 XML 기반의 메시지를 컴퓨터 네트워크 상에서 교환하는 프로토콜이다.
SOAP
은 웹 서비스(WS, Web Service)에서 메시지를 전달을 위해 사용하는 프로토콜입니다.
여기서 말하는 웹 서비스는 월드 와이드 웹(WWW, World Wide Web)을 통해 사용자에게 어떠한 서비스를 하는 것이 아닙니다.
웹 서비스는 다음과 같이 정리할 수 있습니다.
- 서비스 지향적 분산 컴퓨팅 기술의 일종으로 네트워크 상에서 서로 다른 종류의 컴퓨터들 사이에 통신을 위한 기술입니다.
- 웹 서비스는 HTTP, HTTPS, SMTP 같은 프로토콜을 통해 XML이나 JSON 형식으로 메시지(혹은 데이터)를 주고 받는 기술입니다.
- 대표적으로 다음과 같은 기술들이 있습니다.
- AJAX(Asynchronous JavaScript And XML) since 1999
- REST(Representational State Transfer) since 2000
- SOAP since 1998
1.1. Advantages and Disadvantages
많은 글들에서 SOAP
의 장점을 설명하는데 필자는 공감이 잘 안 됐습니다.
요즘엔 당연한 특징들이지만, 1990년도 초반부터 사용한 원격 통신 방식인 CORBA, DCOM, RMI과 비교했을 때 주된 차이점들입니다.
- HTTP, XML을 사용하기 때문에 개발 도구나 플랫폼에 종속적이지 않습니다.
- 기존 방화벽 및 프록시를 통해 쉽게 터널링이 되므로 메시지 교환을 위해 존재하는 광범위한 컴퓨팅 및 통신 인프라를 수정할 필요가 없습니다.
SOAP
은 인터넷을 사용하는 모든 서버에 의해 지원되는 HTTP를 전송 매체로써 사용하기 때문에 쉽게 적용할 수 있습니다.- CORBA, DCOM 등은 호환성과 보안상의 문제로 방화벽에서 차단되는 문제가 있었던 것 같습니다.
다음과 같은 단점들이 있습니다.
- 이름처럼 단순(simple)하지 않습니다.
- 프로토콜 메시지 형식이 장황합니다.
- XML 메시지 구문을 분석하는데 비용이 비쌉니다.
- HTTP를 직접 사용하는 REST 웹 서비스가 우세하게 됩니다.
1.2. Message Format
SOAP
에서 사용하는 메지는 다음과 같은 형식을 가집니다.
- Envelope
- 해당 XML 문서가
SOAP
메시지인지 식별하기 위해 사용합니다. - 필수 항목입니다.
- 해당 XML 문서가
- Header
- 헤더 정보를 담습니다.
- Body
- 요청과 응답에 대한 정보를 담습니다.
- 필수 항목입니다.
- Fault
- 프로세스 중에 발생한 에러 정보를 담습니다.
1.2.1. Request Example
SOAP
요청 메시지는 다음과 같은 형식을 가집니다.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:gs="http://spring.io/guides/gs-producing-web-service">
<soapenv:Header/>
<soapenv:Body>
<gs:getCountryRequest>
<gs:name>Spain</gs:name>
</gs:getCountryRequest>
</soapenv:Body>
</soapenv:Envelope>
이를 JSON 메시지로 표현하면 다음과 같습니다.
{
"name": "Spain"
}
1.2.2. Response
SOAP
응답 메시지는 다음과 같은 형식을 가집니다.
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:getCountryResponse xmlns:ns2="http://spring.io/guides/gs-producing-web-service">
<ns2:country>
<ns2:name>Spain</ns2:name>
<ns2:population>46704314</ns2:population>
<ns2:capital>Madrid</ns2:capital>
<ns2:currency>EUR</ns2:currency>
</ns2:country>
</ns2:getCountryResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
이를 JSON 메시지로 표현하면 다음과 같습니다.
{
"country": {
"name": "Spain",
"population": "46704314",
"capital": "Madrid",
"currency": "EUR"
}
}
2. Web Service Protocol Stacks
SOAP
은 웹 서비스 기술에서 사용되는 메시지 프로토콜 중 하나입니다.
다음과 같은 4개의 프로토콜 스택을 사용해 웹 서비스 시스템을 구축합니다.
- (Service) Transport Protocol
- 네트워크에 존재하는 어플리케이션들 사이에서 메시지를 전송하는 역할을 가집니다.
- e.g. HTTP, SMTP, FTP
- (XML) Messaging Protocol
- 메시지를 인코딩하는 역할을 가집니다.
- e.g. XML-RPC, WS-Addressing, SOAP
- (Service) Description Protocol
- 특정 웹 서비스에 대한 공용 인터페이스를 설명하는데 사용합니다.
- e.g. WSDL
- (Service) Discovery Protocol
- 웹 서비스들이 자신이 제공하는 API 문서를 공개할 수 있는 공용 레지스트리(registry) 서버입니다.
- 공용 레지스트리를 탐색하여 공개된 API 문서를 기반으로 요청과 응답을 받습니다.
- e.g. UDDI
3. Web Service Architecture
웹 서비스는 위에서 설명한 4개의 프로토콜 스택을 사용해 다음과 같은 아키텍처를 구성합니다. 웹 서비스 소비자와 제공자 사이의 통신은 다음과 같은 절차를 통해 진행됩니다.
- 웹 서비스 제공자(provider)는 자신이 제공하는 API를 WSDL 문서로 만들어 UDDI 서버에 배포합니다.
- 웹 서비스 소비자(consumer)는 자신이 필요한 WSDL 문서를 UDDI 서버에서 탐색합니다.
- 소비자는 WSDL 문서를 파싱하여 요청에 필요한 정보를 생성합니다.
- 소비자는 생성한 정보를 기준으로
SOAP
메시지 형식에 맞는 요청 정보를 만듭니다. - 소비자는 HTTP를 통해
SOAP
메시지를 제공자에게 전달합니다. - 제공자는
SOAP
메시지 요청을 받고 필요한 처리를 수행합니다. - 제공자는 처리가 완료되면 HTTP를 통해 소비자에게
SOAP
메시지 응답을 전달합니다.
4. WSDL(Web Services Description Language)
웹 서비스 참여자들은 다음과 같은 용도로 WSDL
문서를 사용합니다.
- 제공자는 자신이 공개하는 API를
WSDL
문서로 만들어 UDDI 서버에 업로드한다. - 소비자는 자신이 필요한 API가 정의된
WSDL
문서를 UDDI 서버에서 탐색하여 사용한다.
WSDL
문서는 XML 기반으로 작성되었으며 .wsdl 확장자를 가지고 UDDI 레지스트리 서버에 저장됩니다.
WSDL2.0
은 WSDL1.1
에 비해 널리 지원되지 않으므로 WSDL1.1
을 기준으로 각 요소에 대해 알아보겠습니다.
- Types
- 교환되는 메시지 설명
- 해당 메시지에서 사용되는 데이터 형식 정의
- Messages
- 어떤 메시지가 교환되는지에 대한 정보가 담깁니다.
- Port Type
- 어떤 요청이 들어왔을 때 어떤 응답을 보내는지에 대해 정의되어 있습니다.
- Binding
- 포트 타입(Port Type)에 대한 메시지 포맷이나 프로토콜, 오퍼레이션(operation)이 정의되어 있습니다.
- Service
- 웹 서비스 URL 엔드포인트(endpoint)가 정의되어 있습니다.
Example
<wsdl:definitions targetNamespace="http://spring.io/guides/gs-producing-web-service">
<!-- TYPES -->
<wsdl:types>
<xs:schema elementFormDefault="qualified" targetNamespace="http://www.baeldung.com/springsoap/gen">
<xs:element name="getCountryRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getCountryResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="country" type="tns:country" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="country">
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="population" type="xs:int" />
<xs:element name="capital" type="xs:string" />
<xs:element name="currency" type="tns:currency" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="currency">
<xs:restriction base="xs:string">
<xs:enumeration value="GBP" />
<xs:enumeration value="EUR" />
<xs:enumeration value="PLN" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
</wsdl:types>
<!-- MESSAGES -->
<wsdl:message name="getCountryResponse">
<wsdl:part element="sch:getCountryResponse" name="getCountryResponse"> </wsdl:part>
</wsdl:message>
<wsdl:message name="getCountryRequest">
<wsdl:part element="sch:getCountryRequest" name="getCountryRequest"> </wsdl:part>
</wsdl:message>
<!-- PORT TYPE -->
<wsdl:portType name="CountriesPort">
<wsdl:operation name="getCountry">
<wsdl:input message="tns:getCountryRequest" name="getCountryRequest"> </wsdl:input>
<wsdl:output message="tns:getCountryResponse" name="getCountryResponse"> </wsdl:output>
</wsdl:operation>
</wsdl:portType>
<!-- BINDING -->
<wsdl:binding name="CountriesPortSoap11" type="tns:CountriesPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getCountry">
<soap:operation soapAction="" />
<wsdl:input name="getCountryRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="getCountryResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- SERVICE -->
<wsdl:service name="CountriesPortService">
<wsdl:port binding="tns:CountriesPortSoap11" name="CountriesPortSoap11">
<soap:address location="http://localhost:8080/ws" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
CLOSING
여전히 옛날 기술을 사용하는 레거시 시스템들이 여전히 있다는 사실을 새삼 느낍니다.
필자가 개발자 커리어를 시작한 18년도에 REST 방식이 표준처럼 사용되고 있었기 때문에 SOAP
방식에 대해 알 필요가 있을까 생각했습니다.
혹시 모를 레거시 시스템 연계를 위해 공부하면서 옛 기술이고 지금은 잘 사용하지 않는다고 “몰라도 된다” 넘길 수 없다는 것을 체감하였습니다.
RECOMMEND NEXT POSTS
REFERENCE
- https://en.wikipedia.org/wiki/SOAP
- https://ko.wikipedia.org/wiki/SOAP
- https://en.wikipedia.org/wiki/Web_service
- https://en.wikipedia.org/wiki/Web_services_protocol_stack
- https://ko.wikipedia.org/wiki/UDDI
- https://www.baeldung.com/spring-boot-soap-web-service
- https://brewagebear.github.io/soap-and-wsdl/
- https://gruuuuu.github.io/programming/soap/
- https://www.nextree.co.kr/p11842/
- https://crabo.ru/ko/the-security-of-your-computer/chto-takoe-web-sluzhba---opisanie-s-pomoshchyu-wsdl-soap-web-servis-sredstvami.html
- https://crunchify.com/basic-wsdl-structure-understanding-wsdl-explained/
댓글남기기