Challenge, and Growth ! GitHub
                                                                                                             

Welcome to my blog 🙌🏻

Total

Today

Yesterday













Network

API 프로토콜 SOAP이란 - 개념, 실습

뽀시라운 2025. 1. 19. 16:04
반응형
SMALL

[목차여기]

 

API 통신이라 하면 HTTP가 가장 먼저 떠오른다. 나도 개발할 때 거의 모든 프로젝트에서 HTTP를 사용했었다. HTTP는 특히 개발 관련 레퍼런스도 많아서 어렵지 않았던 것 같다. 하지만 가끔 HTTP 만으로는 개발하기 어려운 부분이 있었다. 가령, 졸업 프로젝트에서 진행했던 자동매매를 위한 실시간 통신의 경우에는 '소켓 통신'이 필요했다. 

 

SOAP은 은행 간의 계좌 이체, 병원 간의 환자 정보 교환 등 다양한 산업 분야에서 사용된다고 한다. HTTP에만 국한되면 나의 개발 실력도 늘 수 없다고 판단했기에, 이 글에서는 SOAP이 무엇인지 알아보고 간단히 실습을 진행해 볼 것이다.

 

 

 

📁 API, API 프로토콜

API(Application Programming Interface)소프트웨어 간 통신과 데이터를 주고받기 위한 인터페이스다.

 

API는 인터넷 계층에서만 사용되는 것이 아니라, 소프트웨어 간의 통신 전반에서 사용된다. 예를 들어, 클라이언트와 서버가 데이터를 교환하기 위해서 인터넷 기반의 REST API 또는 SOAP API를 사용한다. 운영체제(OS)의 API는 응용 프로그램이 하드웨어 리소스에 접근할 수 있도록 지원한다. API 프로토콜API를 통해 소프트웨어가 서로 통신하거나 데이터를 교환할 때 사용하는 규칙이다.

 

[그림1] API 통신 방식

 

API는 일반적으로 클라이언트와 서버의 통신으로 이루어진다. 요청을 보내는 쪽이 클라이언트고, 응답을 보내는 쪽이 서버다. 어떤 API 프로토콜을 사용할 것인지는 내가 적용하고자 하는 소프트웨어의 특징을 고려하면 된다. 아래는 API 프로토콜을 선택하는 몇 가지 예시다.

  • REST : 간단한 CRUD(Create, Read, Update, Delete) 작업에 적합하다.
  • SOAP : 보안이 중요한 트랜잭션에 적합하다.
  • WebSocket : 실시간 데이터 스트림에 적합하다.

 

 

이제 API 프로토콜 SOAP에 대해서 자세히 알아볼 것이다.

 

 

📁 SOAP(Simple Object Access Protocol)

SOAP는 HTTP, HTTPS, SMTP 등을 통해서 XML 기반의 메시지를 컴퓨터 네트워크 상에서 교환하는 프로토콜이다. 다른 언어로, 다른 플랫폼에서 빌드된 애플리케이션이더라도 SOAP을 사용하면 서로 통신할 수 있다.

 

* 좀 더 정확히 설명하자면, SOAP의 XML 메시지는 단순 데이터 교환뿐 아니라 문서 지향 메시지 교환과 RPC 지향 통신 모두 가능하다.

 

SOAP은 WSDL(Web Services Description Language)을 기반으로 통신한다. WSDL은 XML 기반의 언어이다. 클라이언트가 SOAP API를 호출하려면 서비스의 위치(URL), 사용 가능한 메서드, 메서드의 입출력 형식 등을 알아야 하는데, WSDL이 이것을 정의한다.

 

📌 SOAP 특징

  • 메시지 구조: XML
  • 표준화: WSDL(Web Services Description Language)을 사용해 서비스 인터페이스를 정의하고, 메시지를 표준화한다.
  • 보안: WS-Security와 같은 표준으로 높은 수준의 보안을 제공한다.
  • 표준화된 규격: 산업 표준을 기반으로 하며, 대규모 엔터프라이즈 환경에 적합하다.
  • 트랜잭션 처리: 복잡한 트랜잭션과 상태 관리가 가능하다.
  • 언어 및 플랫폼 독립적: 다양한 환경에서 호환 가능하다.

단점

  • XML 기반 메시지는 상대적으로 크고 처리 비용이 높다.
  • REST보다 구현과 유지보수가 복잡하다.

 

📌 HTTP vs SOAP

우리가 잘 알고 있는 HTTP와 비교한 표이다.

  HTTP SOAP
데이터 형식 JSON, XML 등 다양한 형식 XML
아키텍처 스타일 아키텍처 스타일 프로토콜
보안 별도 구현 필요 WS-Security 지원
표준화 표준이 아님 표준화된 규격
트랜잭션 복잡한 트랜잭션 관리 어려움 복잡한 트랜잭션 관리 가능
사용 용도 웹, 모바일, 간단한 API 엔터프라이즈 시스템

 

 

 

📁 SOAP 실습

클라이언트가 서버에게 `이름`을 전송하면 `Hello, {이름}!`이라고 서버가 응답을 보내는 프로그램을 만들 것이다.

 

[그림2] 실습 과정

 

 

📌 Node.js 에 적용해 보기

먼저 Node.js 프로젝트를 준비한다. 기존의 프로젝트에 적용해도 된다.

 

1️⃣ Node.js 설치 확인

`node -v`

`npm -v`

 

2️⃣ 프로젝트 생성

`mkdir soap-demo`

`cd soap-demo`

`npm init -y`

 

3️⃣ SOAP 라이브러리 설치

`npm install express soap body-parser`

 

 

package.json

 

import 모듈을 해야 하므로 type을 추가한다.

{
  "type": "module", 
}

 

 

 

greeting-service.wsdl

 

앞서, soap은 wsdl 기반으로 동작한다고 했다. 그래서 우리 서비스에 맞게 wsdl을 작성해주어야 한다.

<!-- 정의부 : 서비스의 이름, 네임스페이스 등을 정의 -->
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xs="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://example.com/greeting-service"
             name="GreetingService"
             targetNamespace="http://example.com/greeting-service">
    
    <!-- 데이터 타입 정의 : 웹 서비스에서 사용하는 데이터 구조 기술 -->
    <types>
        <xs:schema targetNamespace="http://example.com/greeting-service">
            <xs:element name="GetGreetingRequest">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="name" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="GetGreetingResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="greeting" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:schema>
    </types>

    <!-- 입출력 메시지 정의, 메시지는 이름과 타입을 지정한다. -->
    <message name="GetGreetingRequest">
        <part name="parameters" element="tns:GetGreetingRequest"/>
    </message>
    <message name="GetGreetingResponse">
        <part name="parameters" element="tns:GetGreetingResponse"/>
    </message>

    <!-- 서비스의 인터페이스를 정의. 메서드와 메시지 정의 -->
    <portType name="GreetingPortType">
        <operation name="GetGreeting">
            <input message="tns:GetGreetingRequest"/>
            <output message="tns:GetGreetingResponse"/>
        </operation>
    </portType>

    <!-- 포트 타입에 프로토콜과 전송 방법 매핑 -->
    <binding name="GreetingBinding" type="tns:GreetingPortType">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="GetGreeting">
            <soap:operation soapAction="http://example.com/greeting-service/GetGreeting"/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>

    <!-- 특정 URL에(엔드포인트)서 서비스가 어디에서 호출될 수 있는지 정의 -->
    <service name="GreetingService">
        <port name="GreetingPort" binding="tns:GreetingBinding">
            <soap:address location="http://localhost:3000/wsdl"/>
        </port>
    </service>
</definitions>

 

사실 XML은 여전히 보기 불편하지만 똑똑한 GPT가 XML 구조를 잘 설명해 주므로 너무 어렵게 생각할 필요는 없는 것 같다. 코드의 끝 부분을 보면 GreetingService를 정의했다. 이것을 서버가 구현할 것이다.

 

 

 

index.js

 

서버 파일이 되는 index.js을 작성해 준다.

import express from 'express';
import soap from 'soap';
import fs from 'fs';

const app = express();
const port = 3000;

// SOAP 서비스 정의
const service = {
  GreetingService: {
    GreetingPort: {
      GetGreeting: (args) => {
        console.log('Request received:', args);
        return {
          greeting: `Hello, ${args.name}!`,
        };
      },
    },
  },
};

// WSDL 파일 로드
const wsdlPath = './greeting-service.wsdl';
const wsdl = fs.readFileSync(wsdlPath, 'utf8');

// SOAP 서버 엔드포인트
app.listen(port, () => {
  soap.listen(app, '/wsdl', service, wsdl);
  console.log(`SOAP server running at http://localhost:${port}/wsdl?wsdl`);
});

 

먼저 SOAP 서비스를 정의한다.

greeting-service.wsdl에 GreetingService를 정의했었다. 클라이언트가 전달하는 args(이름)을 받고 응답을 전달하도록 구현했다.

 

 

fs(파일 시스템 모듈)을 사용해서 WSDL 파일을 동기적으로 읽어온다. wsdlPath에 지정된 경로에서 greeting-service.wsdl 파일을 읽는다. 파일 내용을 UTF-8 인코딩 문자열로 반환하고 반환된 WSDL XML 데이터는 wsdl 변수에 저장된다.

 

 

soap.listen()을 통해 SOAP 서버를 생성하고, 요청을 처리할 엔드포인트를 지정한다.

  • 클라이언트가 `/wsdl?wsdl` 경로로 요청을 보내면 서버는 WSDL 문서를 반환한다.
  • 클라이언트가 `/wsdl` 경로로 요청을 보내면 service 객체에 저장된 로직에 따라 처리한다.

예를 들어서 클라이언트가 GetGreeting 메서드를 호출하면 SOAP 서버가 WSDL에 정의된 내용에 따라 요청을 검증하고 요청이 유효하다면 service 객체에서 GetGreeting 메서드를 실행하게 된다. 응답은 XML 형식이다.

 

 

 

client.js

 

클라이언트 파일이 되는 client.js를 작성해 준다. 클라이언틑 코드를 작성하지 않으면 Postman에서 직접 XML 형태의 응답을 보내야 하므로 작성하기 번거롭다. 그래서 코드를 작성해준다.

import soap from 'soap';

const url = 'http://localhost:3000/wsdl?wsdl';
const requestArgs = { name: 'pposiraun' };

soap.createClient(url, (err, client) => {
  if (err) {
    return console.error('Error creating SOAP client:', err);
  }

  client.GetGreeting(requestArgs, (err, result) => {
    if (err) {
      return console.error('Error calling SOAP service:', err);
    }
    console.log('Response:', result);
  });
});

 

서버에 요청하기 위해서 url과 요청 데이터(이름)를 지정한다. soap.createClient()를 통해 클라이언트 객체를 생성하고, client.GetGreeting()을 통해 WSDL에 정의된 GetGreeting 메서드를 호출한다.

 

 

 

 

이제 `node index.js` 입력해서 서버를 실행하고 클라이언트에서 확인해 보면, 아래 사진처럼 응답을 받을 수 있다. 같은 컴퓨터에서 확인하기 위해서 터미널 창을 2개 띄워주면 된다.

 

[그림3] 왼쪽:서버 / 오른쪽:클라이언트

 

 

 

 

 

 

https://aws.amazon.com/ko/what-is/api/

https://www.w3.org/TR/soap12/

 

 

 

 

웹과 HTTP 동작방식 - 비지속/지속 연결 HTTP, 버전별 특징

[목차여기]  Web은 온디맨드 방식으로 동작한다. 온디맨드(On Demand) 방식이란 클라이언트 프로그램에서 요구를 하면 그 요구를 전달해 주는 것이다. 그래서 필요할 때만 리소스를 가지고 올 수

proysm.tistory.com

 

반응형
LIST
loading