DEV Community

Cover image for 아피독 사전 요청 및 응답 후 스크립트 사용법
Rihpig
Rihpig

Posted on • Originally published at apidog.com

아피독 사전 요청 및 응답 후 스크립트 사용법

일부 요청은 전송 전에 준비가 필요하고, 일부는 응답을 받은 직후 검증·저장이 필요합니다. 예를 들어 결제 API는 타임스탬프와 비밀 키로 계산한 HMAC 서명을 요구하고, 로그인 API는 이후 요청에 사용할 토큰을 반환합니다. 체크아웃 플로우에서는 응답이 실제로 200인지, 올바른 주문 ID를 포함하는지 확인해야 합니다. 이런 작업을 수동으로 처리하면 반복적일 뿐 아니라 팀원과 요청을 공유할 때 쉽게 누락됩니다.

지금 Apidog을 사용해 보세요

스크립트를 사용하면 이 과정을 요청에 포함할 수 있습니다. Apidog에서는 요청에 작은 JavaScript 코드를 연결해 자동 실행할 수 있습니다.

  • 사전 처리 스크립트(Pre Processors): 요청을 보내기 전에 실행
  • 사후 처리 스크립트(Post Processors): 응답을 받은 후 실행

Postman 스크립트를 작성해 본 적이 있다면 Apidog의 pm 객체 API도 익숙할 것입니다. 이 글에서는 다음 구현을 단계별로 다룹니다.

  1. 사전 처리 스크립트에서 HMAC으로 요청 서명하기
  2. 사후 처리 스크립트에서 응답 토큰 추출 및 검증하기
  3. 공용 스크립트로 공통 로직 재사용하기
  4. CLI로 동일한 스크립트를 CI에서 실행하기

자세한 API 동작은 Apidog 스크립팅 문서에서 확인할 수 있습니다.

사전 및 사후 스크립트가 실제로 하는 일

Apidog은 스크립트를 두 단계로 실행합니다.

사전 처리 스크립트: 요청을 만들기 전에 실행

사전 처리 스크립트(Pre Processors)는 요청이 서버로 전송되기 전에 실행됩니다. 다음과 같은 준비 작업에 사용합니다.

  • Unix 타임스탬프 생성
  • HMAC 또는 JWT 서명 계산
  • 임의 주문 ID 생성
  • 환경 변수 값을 헤더 또는 쿼리 파라미터에 주입
  • 요청 본문을 바탕으로 동적 값 생성

이 시점에는 아직 서버 응답이 없으므로 pm.response를 사용할 수 없습니다.

사후 처리 스크립트: 응답을 받은 후 실행

사후 처리 스크립트(Post Processors)는 응답 수신 후 실행됩니다. 다음 작업에 적합합니다.

  • 상태 코드 검증
  • 응답 JSON 구조 검증
  • 로그인 토큰 저장
  • 생성된 리소스 ID 저장
  • 페이지네이션 커서 저장
  • 응답 시간, 헤더, 쿠키 확인

핵심 규칙은 다음과 같습니다.

  1. pm.response사후 처리 스크립트에서만 사용합니다.

    code, status, headers, responseTime, responseSize, text(), json() 모두 여기에 해당합니다.

  2. 변수는 두 단계 사이의 전달 수단입니다.

    사전 처리 스크립트에서 값을 저장하면 요청 헤더·본문·URL에서 사용할 수 있고, 사후 처리 스크립트에서 다시 읽거나 덮어쓸 수 있습니다.

Postman 사용자라면 탭 이름 차이를 먼저 기억하세요.

Postman Apidog
Pre-request Script 사전 처리 스크립트(Pre Processors)
Tests 사후 처리 스크립트(Post Processors)

동작은 유사하지만 UI의 명칭이 다릅니다.

설정: 요청을 열고 스크립트 탭 찾기

아직 설치하지 않았다면 Apidog 다운로드 페이지에서 macOS, Windows 또는 Linux용 앱을 설치합니다.

Apidog에서 스크립트를 추가할 API 요청을 열고 다음 탭을 찾습니다.

  • Params
  • Headers
  • Body
  • 사전 처리 스크립트(Pre Processors)
  • 사후 처리 스크립트(Post Processors)

각 스크립트 탭에서 사용자 정의 스크립트 추가(add a Custom Script)를 선택하면 pm 객체를 사용할 수 있는 JavaScript 편집기가 열립니다.

변수 우선순위 확인하기

Apidog은 같은 이름의 변수가 있을 때 다음 우선순위로 값을 결정합니다.

로컬 변수 > 환경 변수 > 프로젝트 내에서 공유되는 전역 변수 > 팀 내에서 공유되는 전역 변수

예를 들어 환경 변수 base_url을 설정했는데 예상과 다른 값이 사용된다면, 로컬 변수가 이를 덮어쓰고 있을 수 있습니다.

여러 요청에서 지속적으로 사용할 기본값은 Apidog의 전역 매개변수에 두는 것이 좋습니다.

사전 처리 스크립트 예시: HMAC으로 요청 서명하기

결제 API가 모든 요청에 HMAC-SHA256 서명을 요구한다고 가정해 보겠습니다. 이 방식은 웹훅 검증에도 널리 사용되며, Stripe의 서명 문서에서도 비슷한 패턴을 확인할 수 있습니다.

서버가 다음 값을 기대한다고 가정합니다.

  • 현재 Unix 타임스탬프
  • 요청 본문
  • API 비밀 키로 계산한 HMAC-SHA256 서명

1. 환경 변수 준비

먼저 Apidog 환경에 비밀 키를 저장합니다.

payments_api_secret=<YOUR_SECRET>
Enter fullscreen mode Exit fullscreen mode

2. 사전 처리 스크립트 추가

요청의 사전 처리 스크립트(Pre Processors) 탭에서 사용자 정의 스크립트 추가를 선택하고 다음 코드를 입력합니다.

// Pre Processor: 요청 전송 전에 서명 생성
const CryptoJS = require('crypto-js');

// 현재 Unix 타임스탬프(초)
const timestamp = Math.floor(Date.now() / 1000).toString();

// 환경 변수에서 비밀 키 읽기
const secret = pm.environment.get('payments_api_secret');

// 서명 대상 문자열: timestamp + 개행 + 원본 본문
const body = pm.request.body ? pm.request.body.toString() : '';
const payload = timestamp + '\n' + body;

// HMAC-SHA256 서명을 hex 문자열로 생성
const signature = CryptoJS
  .HmacSHA256(payload, secret)
  .toString(CryptoJS.enc.Hex);

// 요청에서 사용할 환경 변수 저장
pm.environment.set('x_timestamp', timestamp);
pm.environment.set('x_signature', signature);

pm.console.log('Signed request at ' + timestamp);
Enter fullscreen mode Exit fullscreen mode

Apidog에는 crypto-js가 내장되어 있으므로 별도 설치가 필요하지 않습니다.

3. 요청 헤더에서 변수 사용

이제 요청의 Headers 탭에 다음 헤더를 추가합니다.

X-Timestamp: {{x_timestamp}}
X-Signature: {{x_signature}}
Enter fullscreen mode Exit fullscreen mode

요청 실행 순서는 다음과 같습니다.

  1. 사전 처리 스크립트가 타임스탬프를 생성합니다.
  2. 요청 본문과 비밀 키로 서명을 계산합니다.
  3. x_timestamp, x_signature 환경 변수를 저장합니다.
  4. Apidog이 {{variableName}} 값을 실제 값으로 치환합니다.
  5. 완성된 헤더와 함께 요청을 전송합니다.

crypto-js 가져오기 주의사항

다음은 지원됩니다.

const CryptoJS = require('crypto-js');
Enter fullscreen mode Exit fullscreen mode

하지만 서브모듈 경로를 직접 가져오는 방식은 지원되지 않습니다.

// 지원되지 않음
const SHA256 = require('crypto-js/sha256');
Enter fullscreen mode Exit fullscreen mode

전체 모듈을 require('crypto-js')로 가져오세요.

서명처럼 요청마다 새로 계산해야 하는 값은 환경 변수의 초기값이 아니라 현재 실행 중인 값으로 처리됩니다. Postman 기준의 비슷한 패턴은 Postman 사전 요청 스크립트 가이드에서도 확인할 수 있습니다.

사후 처리 스크립트 예시: 토큰 추출 및 검증

이제 로그인 API가 다음과 같은 응답을 반환한다고 가정해 보겠습니다.

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 4812,
    "email": "dana@example.com"
  },
  "expires_in": 3600
}
Enter fullscreen mode Exit fullscreen mode

목표는 다음 두 가지입니다.

  1. 응답이 기대한 형식인지 테스트합니다.
  2. 토큰을 저장해 이후 인증 요청에 재사용합니다.

1. 사후 처리 스크립트 추가

로그인 요청의 사후 처리 스크립트(Post Processors) 탭에서 사용자 정의 스크립트 추가를 선택하고 다음 코드를 작성합니다.

// Post Processor: 응답 검증 후 토큰 저장
pm.test('Status is 200', function () {
  pm.response.to.have.status(200);
});

const jsonData = pm.response.json();

pm.test('Response returns a token', function () {
  pm.expect(jsonData.token).to.be.a('string').and.not.empty;
});

pm.test('User id is present', function () {
  pm.expect(jsonData.user.id).to.be.a('number');
});

// 이후 요청에서 사용할 토큰 저장
pm.environment.set('auth_token', jsonData.token);

pm.console.log('Saved token for user ' + jsonData.user.email);
Enter fullscreen mode Exit fullscreen mode

2. 이후 요청에서 토큰 사용

인증이 필요한 다른 요청의 Headers 탭에 다음 값을 설정합니다.

Authorization: Bearer {{auth_token}}
Enter fullscreen mode Exit fullscreen mode

이제 로그인 요청을 한 번 실행하면 이후 요청이 저장된 토큰을 자동으로 사용합니다. 토큰을 복사해 붙여넣을 필요가 없습니다.

어설션을 추가해야 하는 이유

pm.test()pm.expect()를 사용하면 단순히 응답을 눈으로 확인하는 대신 재현 가능한 테스트를 만들 수 있습니다.

예를 들어 다음을 자동 검증할 수 있습니다.

  • 상태 코드가 200인지
  • token이 비어 있지 않은 문자열인지
  • user.id가 숫자인지
  • 특정 헤더가 존재하는지
  • 응답 시간이 기준 이내인지

더 많은 패턴은 Apidog의 API 어설션 가이드에서 확인할 수 있습니다. 테스트에 가짜 데이터가 필요하다면 Apidog의 Faker.js도 함께 사용할 수 있습니다.

사후 처리 단계의 제한 사항

다음 동작도 기억하세요.

  • pm.iterationData는 읽기 전용입니다. 데이터 기반 테스트 값을 읽을 수는 있지만 스크립트에서 수정할 수는 없습니다.
  • pm.cookies는 요청에 보낸 쿠키가 아니라 서버가 응답으로 반환한 쿠키를 가져옵니다.

공용 스크립트로 로직 재사용하기

HMAC 서명 코드가 여러 요청에 필요하다면 각 요청에 복사하지 마세요. 서명 알고리즘이 바뀌면 모든 요청을 수정해야 하기 때문입니다.

Apidog에서는 공용 스크립트(Public Scripts)로 공통 코드를 재사용할 수 있습니다.

공용 스크립트 만들기

  1. 설정(Settings) > 공용 스크립트(Public Scripts)로 이동합니다.
  2. 공통 로직을 작성합니다.
  3. 필요한 요청의 사전 처리 또는 사후 처리 스크립트에 공용 스크립트를 추가합니다.

실행 순서가 중요합니다.

  • 공용 스크립트는 같은 목록의 사용자 정의 스크립트보다 먼저 실행됩니다.
  • 공용 스크립트가 여러 개라면 목록의 위에서 아래 순서로 실행됩니다.

공용 함수는 전역으로 선언하기

공용 스크립트 함수가 뒤에 있는 사용자 정의 스크립트에서 호출되어야 한다면 전역으로 선언해야 합니다.

다음처럼 const, let, var 없이 할당합니다.

// Public Script
sign = function (payload, secret) {
  const CryptoJS = require('crypto-js');

  return CryptoJS
    .HmacSHA256(payload, secret)
    .toString(CryptoJS.enc.Hex);
};
Enter fullscreen mode Exit fullscreen mode

그 아래의 사용자 정의 스크립트에서 함수를 호출합니다.

// Custom Script
const timestamp = Math.floor(Date.now() / 1000).toString();
const secret = pm.environment.get('payments_api_secret');

pm.environment.set('x_timestamp', timestamp);
pm.environment.set('x_signature', sign(timestamp, secret));
Enter fullscreen mode Exit fullscreen mode

다음처럼 선언하면 함수가 해당 스크립트 범위에만 남아 다른 스크립트에서 호출할 수 없습니다.

// 다른 스크립트에서 사용할 수 없음
const sign = function (payload, secret) {
  // ...
};
Enter fullscreen mode Exit fullscreen mode

공용 스크립트를 먼저 배치하고 사용자 정의 스크립트를 그 아래에 두세요. 순서가 반대이거나 함수가 전역으로 선언되지 않으면 정의되지 않은 함수 오류가 발생할 수 있습니다.

라이브러리, 외부 패키지 및 디버깅

Apidog은 일부 라이브러리를 기본 제공하므로 일반 require()로 바로 사용할 수 있습니다.

  • crypto-js v3.1.9-1: 해싱 및 HMAC
  • jsrsasign v10.3.0: JWT 및 RSA 작업, Apidog 1.4.5 이상 필요
  • chai v4.2.0: 어설션 매처
  • lodash
  • moment
  • uuid
  • xml2js
  • cheerio
  • postman-collection
  • atob
  • btoa
  • csv-parse/lib/sync
  • tv4
  • ajv

다음과 같은 Node 내장 모듈도 사용할 수 있습니다.

path
assert
buffer
util
url
querystring
stream
events
Enter fullscreen mode Exit fullscreen mode

외부 npm 패키지 가져오기

내장 목록에 없는 패키지는 $$.liveRequire()로 런타임에 가져올 수 있습니다.

$$.liveRequire('nanoid', (nanoid) => {
  const id = nanoid.nanoid();

  pm.environment.set('request_id', id);
});
Enter fullscreen mode Exit fullscreen mode

$$.liveRequire()는 스크립트 실행 시 패키지를 다운로드하므로 인터넷 연결이 필요합니다. 반면 내장 라이브러리는 네트워크 연결 없이 사용할 수 있습니다.

콘솔 로그로 디버깅하기

스크립트가 예상대로 실행되지 않을 때는 로그를 남기세요.

pm.console.log('timestamp:', timestamp);
pm.console.log('signature:', signature);
Enter fullscreen mode Exit fullscreen mode

또는 일반 JavaScript 콘솔도 사용할 수 있습니다.

console.log('token:', jsonData.token);
Enter fullscreen mode Exit fullscreen mode

pm.console.log()console.log() 출력은 Apidog 콘솔에서 확인할 수 있습니다. 특히 다음을 확인할 때 유용합니다.

  • 계산된 서명이 예상 형식인지
  • 환경 변수에 값이 저장됐는지
  • 응답 JSON에 필요한 필드가 있는지
  • 공용 스크립트가 예상 순서로 실행됐는지

요청 체이닝 관련 제한 사항

pm.sendRequest()는 추가 HTTP 요청을 보낼 수 있지만 Promise 기반이 아니라 콜백 방식으로 사용합니다.

pm.sendRequest('https://example.com/api', function (error, response) {
  if (error) {
    console.log(error);
    return;
  }

  console.log(response.json());
});
Enter fullscreen mode Exit fullscreen mode

따라서 await pm.sendRequest() 방식은 사용할 수 없습니다.

또한 Postman의 pm.nextRequest()는 지원되지 않습니다. 조건 분기와 요청 순서 제어가 필요한 경우 테스트 시나리오(Test Scenarios)를 사용하세요. 테스트 시나리오에서는 Condition 및 If-Else 단계로 요청 흐름을 구성할 수 있습니다.

Apidog CLI로 워크플로우 자동화하기

스크립트는 데스크톱 앱에서 Send를 클릭할 때만 실행되는 것이 아닙니다. 요청과 어설션을 테스트 시나리오로 저장하면 Apidog CLI가 사전 처리 및 사후 처리 스크립트를 포함한 전체 시나리오를 헤드리스로 실행할 수 있습니다.

즉, 다음 작업을 CI에 포함할 수 있습니다.

  • 요청 서명 생성
  • 인증 토큰 추출
  • API 응답 검증
  • 테스트 결과 리포트 생성

CLI 설치 및 실행

npm install -g apidog-cli

apidog login --with-token <YOUR_ACCESS_TOKEN>

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <SCENARIO_ID> \
  -e <ENV_ID> \
  -r cli
Enter fullscreen mode Exit fullscreen mode

옵션의 의미는 다음과 같습니다.

옵션 설명
-t 테스트 시나리오 ID
-e 환경 ID
-r 리포터 형식

리포터는 cli, html, junit을 사용할 수 있으며 여러 형식은 쉼표로 구분할 수 있습니다.

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <SCENARIO_ID> \
  -e <ENV_ID> \
  -r cli,junit
Enter fullscreen mode Exit fullscreen mode

Apidog 계정 설정에서 액세스 토큰을 만든 뒤 CI 환경 변수 APIDOG_ACCESS_TOKEN으로 등록하면, 데스크톱에서 실행하던 동일한 스크립트와 테스트를 CI에서도 실행할 수 있습니다.

CLI 실행 시 주의할 점

로컬 컴퓨터에만 있는 파일이나 이미 설치된 패키지에 의존하면 데스크톱에서는 통과해도 CLI에서는 실패할 수 있습니다.

이식성을 높이려면 다음을 우선 사용하세요.

  • Apidog 기본 제공 라이브러리
  • $$.liveRequire()로 가져오는 외부 패키지
  • 환경 변수 기반 설정

자주 묻는 질문

Apidog 스크립트가 기존 Postman 스크립트와 호환되나요?

대부분 호환됩니다. Apidog은 동일한 pm 객체 API를 사용하므로 아래 코드는 익숙한 방식으로 동작합니다.

pm.environment.set('key', 'value');
pm.response.json();
pm.test('test name', function () {});
pm.expect(value).to.equal('expected');
Enter fullscreen mode Exit fullscreen mode

주요 차이점은 다음과 같습니다.

  • 탭 이름이 Pre-request Script, Tests가 아니라 사전 처리 스크립트와 사후 처리 스크립트입니다.
  • pm.nextRequest() 같은 일부 호출은 지원되지 않습니다.

사전 요청 스크립트에서 pm.response가 undefined인 이유는 무엇인가요?

사전 처리 스크립트는 요청이 전송되기 전에 실행되기 때문입니다. 아직 응답이 존재하지 않으므로 pm.response를 읽을 수 없습니다.

상태 코드, 응답 본문, 응답 헤더를 검사하는 코드는 사후 처리 스크립트에 작성하세요. 사전 단계에서 요청 정보를 읽어야 한다면 pm.request, 변수 또는 라이브러리를 사용하면 됩니다.

하나의 스크립트를 여러 요청에서 어떻게 공유할 수 있나요?

설정(Settings) > 공용 스크립트(Public Scripts)에서 공용 스크립트를 만드세요.

  1. 공통 로직을 한 번 작성합니다.
  2. 각 요청의 사전 처리 또는 사후 처리 스크립트에 연결합니다.
  3. 공용 스크립트를 사용자 정의 스크립트보다 먼저 배치합니다.
  4. 다른 스크립트에서 호출할 함수는 전역으로 선언합니다.

Apidog이 번들로 제공하지 않는 npm 패키지를 가져올 수 있나요?

가능합니다. $$.liveRequire()를 사용하세요.

$$.liveRequire('package-name', (pkg) => {
  // pkg 사용
});
Enter fullscreen mode Exit fullscreen mode

이 방식은 런타임에 패키지를 다운로드하므로 인터넷 연결이 필요합니다. crypto-js, moment, uuid처럼 내장된 라이브러리는 일반 require()를 사용하세요.

스크립트 출력은 어디에서 볼 수 있나요?

pm.console.log() 또는 console.log()를 사용한 뒤 요청 실행 후 Apidog 콘솔에서 확인하세요.

pm.console.log('Calculated signature:', signature);
console.log('Saved token:', jsonData.token);
Enter fullscreen mode Exit fullscreen mode

서명이 계산됐는지, 토큰이 저장됐는지, 변수 값이 예상과 같은지 빠르게 확인할 수 있습니다.

마무리

사전 처리 스크립트와 사후 처리 스크립트를 사용하면 정적인 API 요청을 자동화된 테스트 가능한 요청으로 바꿀 수 있습니다.

실무에서는 다음 순서로 적용해 보세요.

  1. 사전 처리 스크립트에서 타임스탬프, ID, 서명을 생성합니다.
  2. {{variableName}}으로 헤더와 본문에 값을 주입합니다.
  3. 사후 처리 스크립트에서 상태 코드와 응답 구조를 검증합니다.
  4. 토큰, 리소스 ID, 커서 같은 값을 환경 변수에 저장합니다.
  5. 공통 로직은 공용 스크립트로 분리합니다.
  6. 테스트 시나리오와 CLI로 CI에서 반복 실행합니다.

Apidog에서 API 요청 하나를 열고, 먼저 사전 처리 스크립트로 타임스탬프를 생성한 뒤 사후 처리 스크립트로 상태 코드 검증을 추가해 보세요. 한 번의 요청 실행만으로 두 단계가 어떻게 연결되는지 확인할 수 있습니다.

Top comments (0)