본문 바로가기

신입 개발자 면접 기초

웹애플리케이션 서비스가 아닌 웹서비스(WebService), WSDL을 아시나요? (WSDL 문법, 구조, 구문 분석)

반응형

서비스(WebService)는 무엇인가?

* 꽤나 오래된 기술이라서 쉽게 변화하기 힘들거나 변화에 보수적이고 오래전 부터 해왔던 업계에 적용되어 사용되고 있다. (일반적인 소프트웨어 회사에 가는 사람들은 굳이 볼 필요가 없다.)

위키백과에 의하면 '네트워크 상에서 서로 다른 종류의 컴퓨터들 간에 상호작용을 하기 위한 소프트웨어 시스템' 이라고 한다. (상호작용을 위해서는 프로토콜이 필요하다는 것은 예상가능하다.)

웹서비스는 웹 애플리케이션 서비스와 다르다.

웹서비스는 쉽게 설명하기 위해 비약을 하면 API 서버와 유사하다.

어떠한 애플리케이션이든 API서버는 "지정된 올바른 요청"을 하면 그에 해당하는 "답변"을 준다.

마찬가지로 웹서비스는 애플리케이션들이 플랫폼과 프로그래밍 언어와는 독립된 방식으로 통신할 수 있도록 표준 XML 메시지를 통해서 네트워크로 접근될 수 있는 오퍼레이션(Operation)들을 기술하는 소프트웨어 인터페이스라고 할 수 있다.

이런 웹 서비스는 SOAP, WSDL과 같은 공개 표준을 정하여 이를 근간으로 상호 작용이 이루어진다.

* SOAP는 정보 교호나을 목적으로 하는 경량의 XML 기반 프로토콜이다.

- RPC(Remote Procedure Call) 방식

- RPC방식의 정보 교환은 request-response 프로세스를 허용하며, 서비스 End-Point는 프로시져 중심의 메시지를 받아서 적절한 응답 메시지를 작성하여 되돌려 준다.

- 메시지 기반(Message-oriented) 방식(=Document 방식의 교환)

- 메시지 기반 방식은 송신자가 서비스의 응답을 즉각적으로 요구하지 않아도 될때에도 사용이 가능하며, 주로 비즈니스와 여러 가지 형태의 문서 타입을 교환할 필요가 있을 때 사용된다.

SOAP에 대한 자세한 내용은 다른 블로그 포스트에서 알아볼 수 있도록 하고 여기서 집중적으로 다룰 것은 WSDL이다.


WSDL 구문 분석

WSDL : WebService가 제공하는 서비스에 대한 정보를 기술하기 위한 XML 기반 마크업 언어. 특정 비즈니스가 제공하는 서비스를 설명한다.

1
2
3
4
5
6
7
<wsdl:definitions>
    <wsdl:types>...</wsdl:types>
    <wsdl:message>...</wsdl:message>
    <wsdl:portType>...</wsdl:portType>
    <wsdl:binding>...</wsdl:binding>
    <wsdl:service>...</wsdl:service>
</wsdl:definitions>


기본적인 형태는 위와 같이 생겼고 각 엘리먼트에 작성해야할 것들은 아래와 같다.

types : 교환될 메시지 설명, "사용될 데이터 형식" 정의 (스키마에 정의된 타입) -> "데이터 타입 재료"

message : "메소드 이름 및 파라미터" 정의 -> 어떤 메시지를 주고 받을 것이다! 선언

portType : message를 묶어서 하나의 operation으로 만듦 -> 일종의 함수 인터페이스를 정의한다.

binding : portType에 의해 정의된 작업 및 메시지에 대해 메시지 형식과 프로토콜을 정의한다. ->클래스화

service : WebService URL Endpoints를 설정한다.

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
<definitions name="EndorsementSearch"
  targetNamespace="http://namespaces.snowboard-info.com"
  xmlns:es="http://www.snowboard-info.com/EndorsementSearch.wsdl"
  xmlns:esxsd="http://schemas.snowboard-info.com/EndorsementSearch.xsd"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns="http://schemas.xmlsoap.org/wsdl/"
>
  <types>
    <esxsd:schema>
      <esxsd:import schemaLocation="EndorsementSearch.xsd" namespace="http://namespaces.snowboard-info.com" />
    </esxsd:schema>
  </types>
  <!-- omitted types section with content model schema info -->
 
  <message name="GetEndorsingBoarderRequest">
    <part name="body" element="esxsd:GetEndorsingBoarder"/>
  </message>
 
  <message name="GetEndorsingBoarderResponse">
    <part name="body" element="esxsd:GetEndorsingBoarderResponse"/>
  </message>
 
  <portType name="GetEndorsingBoarderPortType">
    <operation name="GetEndorsingBoarder">
      <input message="es:GetEndorsingBoarderRequest"/>
      <output message="es:GetEndorsingBoarderResponse"/>
      <fault message="es:GetEndorsingBoarderFault"/>
    </operation>
  </portType>
 
  <binding name="EndorsementSearchSoapBinding"
           type="es:GetEndorsingBoarderPortType">
    <soap:binding style="document"
                  transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="GetEndorsingBoarder">
      <soap:operation
        soapAction="http://www.snowboard-info.com/EndorsementSearch"/>
      <input>
        <soap:body use="literal"
          namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
      </input>
      <output>
        <soap:body use="literal"
          namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
      </output>
      <fault>
        <soap:body use="literal"
          namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
      </fault>
    </operation>
  </binding>
 
  <service name="EndorsementSearchService">
    <documentation>snowboarding-info.com Endorsement Service</documentation
    <port name="GetEndorsingBoarderPort"
          binding="es:EndorsementSearchSoapBinding">
      <soap:address location="http://www.snowboard-info.com/EndorsementSearch"/>
    </port>
  </service>
 
</definitions>
cs

[WSDL Sample / 출처 : https://www.w3.org/2001/04/wsws-proceedings/uche/wsdl.html]

<types> 부분은 약간 수정했다. 부분 별로 간단하게 구문 분석을 해보겠다.


- Types

먼저 <types>는 이 웹 서비스에서 사용될 타입을 정의한다고 했다. 그런데 타입이 보이지 않는다.

그 이유는 .xsd파일(스키마)로 타입들은 따로 분리해서 import로 가져와서 쓰기 때문이다.

타입이 많이 정의되기 때문에 보통 이런식으로 많이 사용하고 간혹 <types>태그 사이에 직접 기술할 때도 있다.


- Message

<Message>는 GetEndorsingBoarderRequest가 있고 GetEndorsingBoarderResponse가 있다.

즉 Request 메시지와 Response 메시지를 정의한 것이다. 추가로 더 많은 메시지를 정의할 수도 있다.

그리고 <message>태그 안에 part는 파라미터를 의미한다.

즉 (name="body")body라는 이름으로 (element="esxsd:GetEndorsingBoarder")GetEndorsingBoarder타입의 파라미터가 사용될 것을 의미한다.

* 참고로 타입이 정의된 스키마에서 해당 타입이 어떻게 정의되어있는지는 명확히 모르지만, 일반적으로 예상했을 때 esxsd:GetEndorsingBoarder 타입의 complexType(대충 구조체라고 생각하면 됨)이 정의 되어있고 내부적으로 String이든 뭐든 이런 타입이 있을 것이다. 결과적으로는 어떤 구조체(or클래스) 타입이라고 생각하면 된다.


- PortType

<portType>은 위의 두 메시지를 묶어서 하나의 메서드(함수)로 만든다.

하나의 operation으로 만들면서 <input>, <output>, <fault>가 존재하는데 이것은 input=Request, output=Response, fault=error(default)로 생각하면 된다.

즉 들어오는 메시지는 GetEndorsingBoarderRequest이고 return되는 메시지는 GetEndorsingBoarderResponse 이며 실패시 GetEndorsingBoarderFault 메시지를 보낼 것이라고 정의한 것이다.

portType의 이런 input, output, fault는 순서도 중요하다.

만약 output, input 순으로 되어있으면 웹서비스를 하는 서버가 먼저 클라이언트에게 메시지를 보내고 클라이언트에게 메시지를 받는 것을 의미하게 된다.

따라서 4가지 방법이 존재한다. (실제 사용은 2가지 방법만 함)

1. One-way : 단 방향으로 클라이언트가 메시지만 보내는 경우 (input만 있는 경우)

2. Notification : 단 방향으로 서버가 메시지만 보내는 경우 (output만 있는 경우) - 사용하지 않음.

3. Request-response : 클라이언트가 요청을 보내고 해당 메시지에 대한 응답을 해주는 경우(input-output순서)

4. Solicit-response : 서버가 요청을 보내고 클라이언트가 응답해주는 경우(output-input순서) - 사용하지 않음.


--- 이렇게 types, message, portType이 있으면 인터페이스가 만들어진다. (wsdl2java, wsimport)


- Binding

메시지 타입을 정의하고 위에서 정의한 메시지를 매핑한다.

Soap:binding > Soap통신이 가능하게 만들도록 지시한다.

name="binding ID", type="매핑할 portType", style=포맷(RPC/document), transport=통신방법(soap-http, soap- smtp등)

Soap:operation > 이 operation의 SoapAction header의 값, portType에 있는 각각의 메시지를 soap전송에 대한 정의에 매핑함.

Soap:body > input/output 메시지의 상세한 표현 정의

encodingStyle, namespace

1. Literal vs Encoded

Literal : 내부 타입이 WSDL의 XML스키마를 따를 것이다.

encoded : 타입이 encoding rule에서 온다.

2. RPC vs Document

RPC : SOAP메시지가 요청 메시지의 매개변수를 포함하고 응답 메시지의 값을 반환한다.(type섹션없음)

Document : SOAP 메시지는 완전한 XML문서를 포함한다.


- Service

soap address로 해당 웹 서비스가 어디에서 제공될 것인지 endpoint를 지시한다.


이렇게 간단하게 WSDL 구문을 분석해보았다.

WSDL을 이용해서 CXF가 해당 SOAP메시지가 왔을 때 매핑되는 함수로 가서 서비스를 제공할 수 있게 된다.

반응형