SOAP(Simple Object Access Protocol)

4 분 소요


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 메시지인지 식별하기 위해 사용합니다.
    • 필수 항목입니다.
  • 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개의 프로토콜 스택을 사용해 다음과 같은 아키텍처를 구성합니다. 웹 서비스 소비자와 제공자 사이의 통신은 다음과 같은 절차를 통해 진행됩니다.

  1. 웹 서비스 제공자(provider)는 자신이 제공하는 API를 WSDL 문서로 만들어 UDDI 서버에 배포합니다.
  2. 웹 서비스 소비자(consumer)는 자신이 필요한 WSDL 문서를 UDDI 서버에서 탐색합니다.
  3. 소비자는 WSDL 문서를 파싱하여 요청에 필요한 정보를 생성합니다.
  4. 소비자는 생성한 정보를 기준으로 SOAP 메시지 형식에 맞는 요청 정보를 만듭니다.
  5. 소비자는 HTTP를 통해 SOAP 메시지를 제공자에게 전달합니다.
  6. 제공자는 SOAP 메시지 요청을 받고 필요한 처리를 수행합니다.
  7. 제공자는 처리가 완료되면 HTTP를 통해 소비자에게 SOAP 메시지 응답을 전달합니다.

https://gruuuuu.github.io/programming/soap/

4. WSDL(Web Services Description Language)

웹 서비스 참여자들은 다음과 같은 용도로 WSDL 문서를 사용합니다.

  • 제공자는 자신이 공개하는 API를 WSDL 문서로 만들어 UDDI 서버에 업로드한다.
  • 소비자는 자신이 필요한 API가 정의된 WSDL 문서를 UDDI 서버에서 탐색하여 사용한다.

WSDL 문서는 XML 기반으로 작성되었으며 .wsdl 확장자를 가지고 UDDI 레지스트리 서버에 저장됩니다. WSDL2.0WSDL1.1에 비해 널리 지원되지 않으므로 WSDL1.1을 기준으로 각 요소에 대해 알아보겠습니다.

  • Types
    • 교환되는 메시지 설명
    • 해당 메시지에서 사용되는 데이터 형식 정의
  • Messages
    • 어떤 메시지가 교환되는지에 대한 정보가 담깁니다.
  • Port Type
    • 어떤 요청이 들어왔을 때 어떤 응답을 보내는지에 대해 정의되어 있습니다.
  • Binding
    • 포트 타입(Port Type)에 대한 메시지 포맷이나 프로토콜, 오퍼레이션(operation)이 정의되어 있습니다.
  • Service
    • 웹 서비스 URL 엔드포인트(endpoint)가 정의되어 있습니다.

https://gruuuuu.github.io/programming/soap/
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

카테고리:

업데이트:

댓글남기기