SOAP API

SOAP(Simple Object Access Protocol)는 네트워크를 통해 데이터를 교환하기 위한 XML 기반의 메시징 프로토콜이다. 1998년 Microsoft에서 개발되었으며, 2000년대 초반부터 중반까지 기업 애플리케이션 통합의 표준으로 널리 사용되었다.

SOAP API는 SOAP 프로토콜을 사용하여 서비스를 제공하는 웹 서비스 인터페이스이다. 이 API는 애플리케이션이 서로 다른 운영 체제나 프로그래밍 언어로 작성되었더라도 인터넷을 통해 통신할 수 있게 해준다.

간단히 말해, SOAP는 어떤 애플리케이션이 다른 애플리케이션에 메시지를 보내고 응답을 받는 방법을 정의한 규칙의 집합이다. 예를 들어, 은행 애플리케이션이 결제 처리 서비스와 통신하거나, 여행 예약 시스템이 항공사 데이터베이스와 통신할 때 SOAP가 사용될 수 있다.

SOAP의 주요 특징

  1. XML 기반: SOAP 메시지는 XML 형식으로 작성된다.
  2. 프로토콜 독립적: HTTP, SMTP, TCP 등 다양한 전송 프로토콜과 함께 사용 가능하다.
  3. 언어 및 플랫폼 독립적: 다양한 프로그래밍 언어와 플랫폼에서 사용할 수 있다.
  4. 표준화: W3C에서 관리하는 공식 표준이다.
  5. 엄격한 규칙: 메시지 구조와 처리 방식에 대한 명확한 규칙을 제공한다.

SOAP 아키텍처의 핵심 요소

SOAP 메시지 구조

SOAP 메시지는 다음과 같은 구조로 이루어져 있다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
    <!-- 선택적 헤더 정보 -->
    <auth:Credentials xmlns:auth="http://example.org/auth">
      <auth:Username>사용자</auth:Username>
      <auth:Password>비밀번호</auth:Password>
    </auth:Credentials>
  </soap:Header>
  <soap:Body>
    <!-- 필수 본문 내용 -->
    <m:GetStockPrice xmlns:m="http://example.org/stock">
      <m:StockName>IBM</m:StockName>
    </m:GetStockPrice>
  </soap:Body>
</soap:Envelope>

주요 구성 요소:

WSDL (Web Services Description Language)

WSDL은 웹 서비스를 설명하는 XML 기반 인터페이스 정의 언어이다. SOAP 서비스의 “계약"이라고 볼 수 있다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="StockQuote"
             targetNamespace="http://example.org/stock/wsdl"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://example.org/stock/wsdl"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
    <!-- 데이터 타입 정의 -->
    <types>
        <xsd:schema targetNamespace="http://example.org/stock/xsd">
            <xsd:element name="GetStockPriceRequest">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="StockName" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="GetStockPriceResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="Price" type="xsd:decimal"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:schema>
    </types>
    
    <!-- 메시지 정의 -->
    <message name="GetStockPriceInput">
        <part name="body" element="xsd:GetStockPriceRequest"/>
    </message>
    <message name="GetStockPriceOutput">
        <part name="body" element="xsd:GetStockPriceResponse"/>
    </message>
    
    <!-- 포트 타입 정의 -->
    <portType name="StockQuotePortType">
        <operation name="GetStockPrice">
            <input message="tns:GetStockPriceInput"/>
            <output message="tns:GetStockPriceOutput"/>
        </operation>
    </portType>
    
    <!-- 바인딩 정의 -->
    <binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="GetStockPrice">
            <soap:operation soapAction="http://example.org/GetStockPrice"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    
    <!-- 서비스 정의 -->
    <service name="StockQuoteService">
        <port name="StockQuotePort" binding="tns:StockQuoteSoapBinding">
            <soap:address location="http://example.org/stockquote"/>
        </port>
    </service>
</definitions>

WSDL 문서의 주요 구성 요소:

XSD (XML Schema Definition)

XSD는 XML 문서의 구조와 내용을 정의하는 스키마 언어이다.
SOAP 메시지 내의 데이터 타입과 구조를 정의하는 데 사용된다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://example.org/stock"
           xmlns:tns="http://example.org/stock"
           elementFormDefault="qualified">
  
  <xsd:element name="GetStockPrice">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="StockName" type="xsd:string"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  
  <xsd:element name="StockPriceResponse">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Price" type="xsd:decimal"/>
        <xsd:element name="Currency" type="xsd:string"/>
        <xsd:element name="LastUpdate" type="xsd:dateTime"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  
</xsd:schema>

UDDI (Universal Description, Discovery and Integration)

UDDI는 웹 서비스 디렉터리로, 비즈니스와 웹 서비스를 등록하고 검색하기 위한 플랫폼이다.
현대 개발에서는 덜 사용되지만, SOAP 에코시스템의 중요한 부분이다.

SOAP 통신 패턴

요청-응답 패턴

가장 일반적인 패턴으로, 클라이언트가 요청을 보내고 서버가 응답한다.

요청 예시:

1
2
3
4
5
6
7
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <m:GetStockPrice xmlns:m="http://example.org/stock">
      <m:StockName>IBM</m:StockName>
    </m:GetStockPrice>
  </soap:Body>
</soap:Envelope>

응답 예시:

1
2
3
4
5
6
7
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <m:GetStockPriceResponse xmlns:m="http://example.org/stock">
      <m:Price>95.72</m:Price>
    </m:GetStockPriceResponse>
  </soap:Body>
</soap:Envelope>

오류 처리 (Fault)

SOAP은 표준화된 오류 처리 메커니즘을 제공한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <soap:Fault>
      <soap:Code>
        <soap:Value>soap:Sender</soap:Value>
      </soap:Code>
      <soap:Reason>
        <soap:Text xml:lang="en">Stock not found</soap:Text>
      </soap:Reason>
      <soap:Detail>
        <e:StockError xmlns:e="http://example.org/stock/error">
          <e:Message>Stock 'XYZ' does not exist</e:Message>
          <e:ErrorCode>E123</e:ErrorCode>
        </e:StockError>
      </soap:Detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

SOAP Fault 요소의 주요 구성 요소:

SOAP API 개발에 필요한 기술과 도구

필수 기술

SOAP API를 효과적으로 개발하기 위해 알아야 할 기술:

  1. XML 기초: 태그, 속성, 네임스페이스, 스키마 등
  2. HTTP 프로토콜: 요청/응답 주기, 상태 코드, 헤더 등
  3. 웹 서비스 기본 개념: 원격 프로시저 호출(RPC), 서비스 지향 아키텍처(SOA)
  4. 보안 개념: 인증, 권한 부여, 암호화, WS-Security
  5. 네트워킹 기초: TCP/IP, 포트, 방화벽 등

개발 도구

SOAP API 개발 및 테스트에 유용한 도구:

  1. SoapUI: SOAP 웹 서비스 테스트를 위한 오픈 소스 도구
  2. Postman: API 테스트 도구(SOAP 지원)
  3. Wireshark: 네트워크 패킷 분석 도구
  4. XML Spy: XML 편집 및 검증 도구
  5. Eclipse/IntelliJ IDEA: 통합 개발 환경(IDE)과 SOAP 플러그인

SOAP API의 보안

SOAP 웹 서비스 보안을 위한 주요 기술과 표준:

WS-Security (Web Services Security)

WS-Security는 SOAP 메시지의 무결성, 기밀성 및 인증을 보장하기 위한 표준이다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <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>사용자명</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">비밀번호</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap:Header>
  <soap:Body>
    <!-- 메시지 본문 -->
  </soap:Body>
</soap:Envelope>
인증 (Authentication)

사용자 자격 증명을 제공하여 신원을 확인한다.
일반적인 방법은 다음과 같다:

1
2
3
4
5
6
7
8
<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>user123</wsse:Username>
         <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass456</wsse:Password>
      </wsse:UsernameToken>
   </wsse:Security>
</soap:Header>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<soap:Header>
   <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:BinarySecurityToken 
         EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
         ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
         wsu:Id="X509Token">
         <!-- Base64로 인코딩된 X.509 인증서 -->
      </wsse:BinarySecurityToken>
   </wsse:Security>
</soap:Header>
무결성 (Integrity)

메시지가 전송 중에 변경되지 않았음을 보장한다. 일반적으로 XML 서명을 사용한다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<soap:Header>
   <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <!-- 인증 토큰 -->
      <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>Hash값</ds:DigestValue>
            </ds:Reference>
         </ds:SignedInfo>
         <ds:SignatureValue>서명값</ds:SignatureValue>
      </ds:Signature>
   </wsse:Security>
</soap:Header>
기밀성 (Confidentiality)

메시지 내용이 권한이 없는 사람에게 노출되지 않도록 보호한다. 일반적으로 XML 암호화를 사용한다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<soap:Body>
   <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
      Type="http://www.w3.org/2001/04/xmlenc#Content">
      <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
         <!-- 키 정보 -->
      </ds:KeyInfo>
      <xenc:CipherData>
         <xenc:CipherValue>암호화된 데이터</xenc:CipherValue>
      </xenc:CipherData>
   </xenc:EncryptedData>
</soap:Body>

주요 보안 메커니즘

  1. XML 서명: 디지털 서명을 사용하여 메시지의 무결성과 송신자 인증을 보장한다.
  2. XML 암호화: 중요한 데이터를 암호화하여 기밀성을 유지한다.
  3. SAML 토큰: 사용자 인증 및 권한 부여 정보를 전달한다.
  4. Transport Layer Security (TLS): HTTPS를 통한 전송 계층 보안을 제공한다.

SOAP vs. REST vs. GraphQL

현대 API 아키텍처의 주요 접근 방식들을 비교해보면:

SOAP vs. REST

특성SOAPREST
프로토콜/스타일프로토콜아키텍처 스타일
데이터 형식XML 전용다양한 형식(JSON, XML, HTML 등)
통신주로 HTTP POST 메서드다양한 HTTP 메서드(GET, POST, PUT, DELETE 등)
상태자체적으로 상태를 포함(stateful 가능)상태 비저장(stateless)
서비스 정의WSDL 사용보통 OpenAPI(Swagger)로 문서화
오류 처리표준화된 SOAP FaultHTTP 상태 코드
캐싱제한적내장 지원(HTTP 캐싱)
복잡성상대적으로 복잡함상대적으로 단순함
확장성WS-* 표준으로 확장 가능상대적으로 제한적
보안WS-Security 등의 확장으로 강력한 보안주로 TLS와 OAuth 사용
사용 적합성엔터프라이즈 시스템, 금융 서비스웹/모바일 앱, 마이크로서비스

SOAP vs. GraphQL

특성SOAPGraphQL
데이터 형식XMLJSON
쿼리 방식미리 정의된 메서드 호출클라이언트가 필요한 데이터 명시
오버페칭자주 발생최소화
엔드포인트일반적으로 단일 엔드포인트단일 엔드포인트
타입 시스템XSD 기반스키마 기반
상태 변경내장된 메커니즘뮤테이션을 통해 지원
개발 경험상대적으로 복잡함개발자 친화적
클라이언트 유연성제한적매우 유연함
버전 관리명시적인 버전 필요스키마 진화로 암시적 관리
사용 적합성엔터프라이즈 통합복잡한 데이터 요구사항의 클라이언트

SOAP API 디버깅 및 문제 해결

SOAP API 개발 시 흔한 문제와 해결 방법:

일반적인 오류

  1. 잘못된 XML 형식: 정확한 XML 문법을 확인한다.
  2. WSDL 문제: WSDL 유효성을 검사하고 모든 필요한 정의가 포함되어 있는지 확인한다.
  3. 네임스페이스 오류: 모든 네임스페이스 선언과 참조가 일치하는지 확인한다.
  4. Schema 유효성 문제: 요청과 응답이 XSD 스키마를 준수하는지 확인한다.
  5. SOAP 버전 불일치: 클라이언트와 서버가 동일한 SOAP 버전을 사용하는지 확인한다.

디버깅 도구와 기법

  1. XML 메시지 검사: 요청 및 응답 메시지를 검사하여 형식과 내용이 올바른지 확인한다.
  2. 네트워크 모니터링: Wireshark나 Fiddler와 같은 도구로 HTTP 트래픽을 캡처하고 분석한다.
  3. 로깅 활성화: 클라이언트와 서버 모두에서 SOAP 메시지 로깅을 활성화한다.
  4. 단계별 테스트: 복잡한 요청을 더 작은 부분으로 나누어 단계별로 테스트한다.

SOAP API의 장점과 단점

SOAP API를 사용할지 결정하기 전에 주요 장점과 단점을 이해하는 것이 중요하다.

장점

  1. 강력한 타입 시스템:
    • WSDL과 XSD를 통해 엄격한 데이터 계약을 정의한다.
    • 컴파일 시점에 많은 오류를 발견할 수 있다.
  2. 언어 및 플랫폼 독립성:
    • 다양한 프로그래밍 언어와 플랫폼 간의 통신을 지원한다.
    • 이기종 시스템 통합에 유용하다.
  3. 표준화된 오류 처리:
    • 내장된 오류 처리 메커니즘이 일관된 방식으로 오류를 전달한다.
    • 애플리케이션 수준의 오류를 체계적으로 처리할 수 있다.
  4. 확장성:
    • WS-* 표준 모음을 통해 보안, 트랜잭션, 메시징 등 다양한 기능을 확장할 수 있다.
    • 엔터프라이즈급 요구사항을 충족시킬 수 있다.
  5. 트랜잭션 지원:
    • WS-AtomicTransaction과 같은 확장을 통해 분산 트랜잭션을 지원한다.
    • 복잡한 비즈니스 프로세스에 적합하다.
  6. 다양한 전송 프로토콜 지원:
    • HTTP, SMTP, JMS 등 다양한 전송 프로토콜을 사용할 수 있다.
    • 환경에 맞는 유연한 통신 옵션을 제공한다.

단점

  1. 복잡성:
    • XML 기반 메시지 형식은 복잡하고 장황할 수 있다.
    • 개발 및 디버깅이 어려울 수 있다.
  2. 오버헤드:
    • XML 파싱과 처리는 상대적으로 많은 리소스를 필요로 한다.
    • 모바일 애플리케이션이나 대량의 트래픽이 있는 환경에서는 성능 문제가 발생할 수 있다.
  3. 대역폭 사용량:
    • XML 형식은 JSON과 같은 다른 형식에 비해 더 많은 대역폭을 소비한다.
    • 네트워크 효율성이 떨어질 수 있다.
  4. 학습 곡선:
    • WSDL, XSD, SOAP 엔벨로프 등의 개념을 이해하는 데 시간이 필요하다.
    • REST와 같은 더 단순한 대안에 비해 진입 장벽이 높다.
  5. 브라우저 지원 제한:
    • 웹 브라우저에서 직접 SOAP API를 호출하는 것이 어렵다.
    • 자바스크립트에서 SOAP를 사용하려면 추가 라이브러리나 프록시가 필요하다.
  6. 유연성 부족:
    • 엄격한 계약 기반 통신으로 인해 API를 변경하기가 어렵다.
    • 작은 변경이라도 클라이언트와 서버 모두에 영향을 미칠 수 있다.
  7. 개발 도구 지원 감소:
    • 최근에는 REST와 GraphQL에 초점을 맞춘 도구가 더 많이 개발되고 있다.
    • SOAP를 위한 최신 도구와 라이브러리 지원이 감소하고 있다.

4. SOAP API 구현하기: 단계별 가이드

Java와 JAX-WS(Java API for XML Web Services)를 사용한 예시를 제공하지만, 다양한 언어와 프레임워크로 SOAP 서비스를 구현할 수 있다.

서버 측 구현 (Java)

1. 웹 서비스 인터페이스 정의
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package com.example.stockservice;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;

@WebService(serviceName = "StockQuoteService")
public interface StockQuoteService {
    
    @WebMethod
    public float getStockPrice(@WebParam(name = "stockName") String stockName);
}
2. 인터페이스 구현
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.stockservice;

import javax.jws.WebService;
import java.util.HashMap;
import java.util.Map;

@WebService(endpointInterface = "com.example.stockservice.StockQuoteService")
public class StockQuoteServiceImpl implements StockQuoteService {
    
    private Map<String, Float> stockPrices = new HashMap<>();
    
    public StockQuoteServiceImpl() {
        // 샘플 데이터 초기화
        stockPrices.put("IBM", 176.25f);
        stockPrices.put("AAPL", 149.35f);
        stockPrices.put("MSFT", 338.11f);
        stockPrices.put("GOOGL", 128.45f);
    }
    
    @Override
    public float getStockPrice(String stockName) {
        if (!stockPrices.containsKey(stockName)) {
            throw new RuntimeException("Stock not found: " + stockName);
        }
        return stockPrices.get(stockName);
    }
}
3. 웹 서비스 게시
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package com.example.stockservice;

import javax.xml.ws.Endpoint;

public class StockQuotePublisher {
    public static void main(String[] args) {
        // 웹 서비스 엔드포인트 게시
        Endpoint.publish("http://localhost:8080/stockservice", new StockQuoteServiceImpl());
        System.out.println("Stock Quote Service is published at http://localhost:8080/stockservice");
    }
}

이 코드를 실행하면 JAX-WS는 자동으로 WSDL 문서를 생성하고 SOAP 메시지를 처리하는 엔드포인트를 설정한다.

클라이언트 측 구현 (Java)

1. WSDL로부터 클라이언트 코드 생성

JAX-WS는 WSDL 파일로부터 클라이언트 코드를 생성할 수 있는 도구를 제공한다. 명령줄에서 다음과 같이 사용할 수 있다:

1
wsimport -keep -p com.example.stockclient http://localhost:8080/stockservice?wsdl

이 명령은 WSDL을 분석하여 필요한 Java 클래스를 생성한다.

2. 생성된 클라이언트 사용
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.example.stockclient;

public class StockQuoteClient {
    public static void main(String[] args) {
        // 서비스 및 포트 생성
        StockQuoteService_Service service = new StockQuoteService_Service();
        StockQuoteService port = service.getStockQuoteServicePort();
        
        // 주식 가격 요청
        try {
            String stockName = "IBM";
            float price = port.getStockPrice(stockName);
            System.out.println("The price of " + stockName + " is $" + price);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

다른 언어로 구현하기

SOAP는 언어에 독립적이므로 다양한 프로그래밍 언어로 구현할 수 있다:

Python (zeep 라이브러리 사용)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from zeep import Client

# WSDL URL로 클라이언트 생성
client = Client('http://localhost:8080/stockservice?wsdl')

# 서비스 호출
stock_name = 'IBM'
result = client.service.getStockPrice(stockName=stock_name)

print(f"The price of {stock_name} is ${result}")

용어 정리

용어설명

참고 및 출처