본문으로 건너뛰기
입문약 25분

Swagger UI 실전: Try it out으로 API 두드리기, Authorize로 토큰 걸기

브라우저 주소창 하나로 API를 바로 실행해보는 Swagger UI의 화면을 읽고, Try it out → Execute 흐름으로 요청을 보내고, 로그인이 필요한 API를 Authorize 버튼으로 인증해 테스트한다.

  • #Swagger
  • #SwaggerUI
  • #OpenAPI
  • #인증토큰
  • #API테스트

개념

Swagger, OpenAPI, Swagger UI — 셋을 먼저 갈라놓자

실무 대화에서 "스웨거 봤어요?"라는 한 문장이 서로 다른 세 가지를 가리킨다. 여기서 헷갈리면 이후 모든 설명이 흐려지므로 먼저 정리한다.

말실체QA가 만나는 모습
OpenAPIAPI를 기술하는 표준 규격 (YAML/JSON 문서)/v3/api-docs, openapi.json 같은 주소의 긴 JSON
Swagger UI그 규격 문서를 사람이 읽고 실행할 수 있는 화면 으로 그려주는 도구/swagger-ui.html, /docs 같은 주소의 웹 페이지
Swagger (넓은 뜻)위 규격과 도구 모음을 만든 회사·제품군의 이름팀에서는 보통 "Swagger UI 화면"을 뜻한다

원래 규격 이름이 Swagger였다가 2015년 표준화되면서 OpenAPI 로 이름이 바뀌었다. 그래서 "Swagger 스펙"과 "OpenAPI 스펙"은 사실상 같은 말이고, 모듈 12(레슨 4)에서 계약 테스트의 근거로 쓴 그 스펙 파일이 바로 Swagger UI 화면이 읽어들이는 원본이다.

핵심은 이것이다. Swagger UI는 스펙을 그려줄 뿐, 스스로 문서를 쓰지 않는다. 화면에 보이는 모든 설명·필드·예시는 서버 코드에서 생성된 스펙에서 나온다. 그래서 코드가 바뀌면 화면도 따라 바뀌고, 반대로 코드에 주석이 부실하면 화면도 똑같이 부실하다.

화면은 세 덩어리로 읽는다

처음 Swagger UI를 열면 알록달록한 줄이 수십 개 쏟아져 당황하기 쉽지만, 구조는 단순하다.

┌─────────────────────────────────────────────┐
│ API 제목 · 버전 · 서버 주소 선택   [Authorize]│  ← ① 머리말
├─────────────────────────────────────────────┤
│ ▼ order  (태그 = 기능 묶음)                  │
│    GET    /orders/{id}    주문 단건 조회   🔓 │  ← ② 엔드포인트 목록
│    POST   /orders         주문 생성       🔒 │
│    DELETE /orders/{id}    주문 취소       🔒 │
├─────────────────────────────────────────────┤
│ ▼ Schemas                                    │
│    Order { id, status, totalPrice, ... }     │  ← ③ 데이터 모양 사전
└─────────────────────────────────────────────┘

① 머리말 — API 이름과 버전, 그리고 요청이 실제로 날아갈 서버 주소 가 있다. 드롭다운으로 개발·스테이징을 고를 수 있는 경우가 많은데, 여기를 확인하지 않고 테스트하다 운영 서버에 주문을 생성해버리는 사고가 실제로 난다. Authorize 버튼도 여기 있다.

② 엔드포인트 목록 — 색깔이 곧 HTTP 메서드다(GET 파랑, POST 초록, PUT 주황, DELETE 빨강). 태그(order, user 등)로 묶여 있고, 줄 오른쪽 자물쇠 아이콘은 "이 API는 인증이 필요하다" 는 표시다.

③ Schemas — 응답·요청에 쓰이는 데이터 구조 사전이다. 어떤 필드가 필수(* 표시)이고 타입이 무엇인지, enum으로 값이 제한돼 있는지가 여기 다 있다. 테스트 설계의 재료가 가장 많이 나오는 곳 이다.

실행 흐름 6단계

한 엔드포인트 줄을 클릭해 펼친 뒤 순서대로 간다.

  1. 접속 — 개발자가 알려준 Swagger UI 주소를 브라우저로 연다.
  2. API 선택 — 테스트할 줄을 눌러 펼친다. Parameters(입력)와 Responses(응답 예시)가 보인다.
  3. Try it out — 오른쪽 위 버튼을 누른다. 이때부터 입력칸이 읽기 전용에서 편집 가능 으로 바뀐다.
  4. 값 입력 — 경로 변수({id}), 쿼리 파라미터, 요청 본문(JSON)을 채운다. 본문은 예시가 미리 채워져 있으니 필요한 값만 고치면 된다.
  5. Execute — 누르는 순간 브라우저가 진짜 서버로 요청을 보낸다. 시뮬레이션이 아니라 실제 호출 이다.
  6. 결과 확인 — 응답 코드·본문·헤더, 그리고 그 위의 curl 명령과 Request URL이 함께 나온다.

Execute 아래 나오는 curl과 Request URL이 진짜 쓸모 있다

많은 사람이 응답 본문만 보고 지나치는데, QA에게는 그 위 두 줄이 더 값지다.

curl -X 'POST' \
  'https://api-dev.example.com/v1/orders' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer eyJhbGciOi...' \
  -H 'Content-Type: application/json' \
  -d '{"itemId": 1001, "quantity": 2}'

이 한 덩어리가 재현 절차 그 자체 다. 결함 리포트에 붙여 넣으면 개발자가 똑같은 요청을 그대로 재현할 수 있다 — 모듈 6에서 배운 "재현 가능한 결함 리포트"를 API 레벨에서 가장 싸게 만드는 방법이다. 다만 토큰이 그대로 박혀 있으므로, 붙여 넣기 전에 Bearer ... 값은 <TOKEN> 으로 지우는 습관을 들인다.

인증(토큰) 설정 — Authorize 버튼의 정체

자물쇠가 달린 API를 그냥 Execute 하면 401 Unauthorized가 돌아온다. 로그인한 사용자로 실행하려면 오른쪽 위 Authorize 버튼 을 눌러 자격 증명을 한 번 등록해야 한다. 등록하면 이후 모든 요청에 자동으로 붙는다.

어떤 입력창이 뜨는지는 스펙의 securitySchemes가 결정한다. 실무에서 만나는 건 대개 이 셋이다.

components:
  securitySchemes:
    bearerAuth:            # ① 가장 흔함 — JWT 토큰
      type: http
      scheme: bearer
      bearerFormat: JWT
    apiKeyAuth:            # ② 헤더에 키를 그대로 싣는 방식
      type: apiKey
      in: header
      name: X-API-KEY
    oauth2Auth:            # ③ 인가 서버를 거쳐 토큰을 받아오는 방식
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/authorize
          tokenUrl: https://auth.example.com/token
          scopes:
            read:orders: 주문 조회

① bearer 방식에서 가장 많이 나는 실수 하나만 기억하자. type: http, scheme: bearer 로 정의된 경우 Swagger UI가 Bearer 접두어를 자동으로 붙인다. 그런데 습관적으로 Bearer eyJhb... 을 통째로 붙여 넣으면 실제 헤더가 이렇게 나간다.

Authorization: Bearer Bearer eyJhbGciOi...   ← 401. 입력창에는 토큰만 넣는다

반면 ② apiKey 방식은 입력한 문자열이 그대로 헤더에 실린다. 즉 접두어가 필요하면 직접 넣어야 한다. "붙여 넣는 값이 같아도 방식에 따라 결과가 다르다"는 점이 초심자가 가장 오래 헤매는 지점이다.

③ OAuth2 는 입력창 대신 팝업으로 인가 서버 로그인 화면이 뜨고, 돌아오면 토큰이 자동으로 채워진다. 이때 화면에 보이는 스코프 체크박스가 곧 권한 테스트의 재료 다 — read:orders만 체크하고 주문 생성을 호출해 403이 나오는지 보는 식으로 권한 경계를 확인할 수 있다.

토큰은 어디서 구하나

QA가 가장 자주 막히는 현실적인 문제다. 경로는 셋 중 하나다.

  • 같은 Swagger 안의 로그인 API를 먼저 실행 한다. POST /auth/login 에 테스트 계정을 넣고 Execute → 응답 본문의 accessToken 값을 복사 → Authorize에 붙여 넣는다. 가장 깔끔한 방법이고, 이 자체가 "로그인 API 테스트"를 겸한다.
  • 개발자에게 발급받는다. 이때 유효기간과 권한(역할) 을 반드시 같이 묻는다. "관리자 토큰인지 일반 사용자 토큰인지"를 모르고 테스트하면 권한 결함을 통째로 놓친다.
  • 웹 화면에 로그인한 뒤 개발자도구 Network 탭에서 요청 헤더의 Authorization 값을 복사한다(모듈 19 레슨 4의 프록시·모듈 9의 DevTools 기법과 같은 자리).

토큰에는 만료 시간 이 있다. 30분쯤 뒤 갑자기 모든 요청이 401로 바뀌면 십중팔구 서버가 죽은 게 아니라 토큰이 만료된 것이다. 브라우저를 새로고침하면 Authorize 등록도 함께 풀린다는 점도 같이 기억한다.

응답에서 QA가 실제로 봐야 할 네 가지

Execute 후 "200 나왔네, 통과"로 끝내면 도구를 절반만 쓴 것이다.

  • 상태 코드 — 성공 경로뿐 아니라 잘못된 입력에 대해 400인지 500인지가 중요하다. 잘못 보냈는데 500이 오면 그 자체가 결함 이다 (서버가 방어하지 못하고 터졌다는 뜻).
  • 본문의 실제 값 — 스펙의 예시가 아니라 돌아온 값이다. number로 선언된 totalPrice에 "9000" 문자열이 오는 식의 계약 위반은 모듈 12(레슨 4)에서 본 그대로다.
  • 헤더 — Content-Type, 캐시 헤더, 그리고 페이지네이션 정보가 헤더에 실리는 API도 많다.
  • Response duration — Swagger UI는 응답 시간을 함께 보여준다. 조회 한 건이 3초라면 그것만으로 성능 이슈 제보 근거가 된다.

실무에서 왜 필요한가

QA가 API를 직접 두드릴 수 있으면 결함의 위치를 한 단계 좁혀서 말할 수 있다. 화면에 주문 금액이 잘못 나올 때 "화면이 이상합니다"가 아니라 "GET /orders/1001 응답의 totalPrice가 이미 9000으로 옵니다 — 서버 쪽입니다"까지 말하는 것과는 대응 속도가 다르다.

그리고 Swagger UI는 설치가 필요 없다. 신입이 입사 첫 주에, 혹은 외부 협력사 QA가 계정만 받은 상태에서 즉시 API 테스트를 시작할 수 있는 유일한 경로인 경우가 많다. 프런트엔드 화면이 아직 없는 기능도 API만 완성됐다면 Swagger로 먼저 검증해 테스트를 왼쪽으로 당길 수 있다 — 모듈 11에서 배운 시프트 레프트의 가장 값싼 실천이다.

마지막으로, Swagger UI 화면은 개발자와 QA가 같은 것을 보고 말하게 만든다. "이 API에 status 필드 있나요?"라는 질문이 오가는 대신 같은 URL을 함께 보면서 "여기 enum에 CANCELED가 없는데 취소 상태는 뭘로 오나요?" 같은 구체적 질문으로 바뀐다.

실습 과제

과제 1 — 공개 데모에서 6단계 흐름 익히기 (10분)

Swagger Petstore 데모에 접속해 다음을 수행한다.

  1. POST /pet 을 펼쳐 Try it out → 예시 JSON의 name을 자기 이름으로 바꾸고 Execute. 응답 코드와 생성된 id를 적는다.
  2. GET /pet/{petId} 로 방금 만든 id를 조회해 값이 그대로인지 본다.
  3. 존재하지 않는 id(예: 999999999)로 조회하고 상태 코드와 응답 본문의 형태 를 적는다.
  4. petId 자리에 숫자가 아닌 문자열 abc를 넣고 Execute 한다.
해설 보기

4번이 이 과제의 핵심이다. 숫자여야 할 자리에 문자열을 넣었을 때 400(잘못된 요청)이 오면 서버가 방어하고 있는 것 이고, 500이 오면 입력 검증 없이 그대로 처리하다 터진 것이다. 후자는 그 자체로 결함이며, 모듈 3에서 배운 동등 분할의 "유효하지 않은 분할"을 API 레벨에서 실행한 결과다.

3번의 응답 본문 형태도 중요하다. 에러 응답이 {"code":1,"message": "Pet not found"} 처럼 일정한 구조 인지, 아니면 어떤 API는 문자열, 어떤 API는 객체로 제각각인지가 프런트엔드 에러 처리 품질을 좌우한다. 제각각이라면 그것은 "문서에 안 적힌 결함"이다.

과제 2 — 인증 흐름 한 바퀴 돌리기 (10분)

같은 Petstore에서 POST /user/login(사용자명 test, 비밀번호 아무 값)을 실행하면 응답 본문에 토큰 성격의 문자열이 온다. 이 값을 복사해 오른쪽 위 Authorize에 등록한 뒤, 자물쇠가 달린 API를 하나 호출해 요청 헤더가 어떻게 바뀌는지 curl 블록에서 확인한다.

그다음 일부러 틀린 토큰(끝 글자 하나를 바꾼 값)으로 다시 등록해 호출하고, 응답 코드가 어떻게 달라지는지 적는다. 401과 403이 각각 무엇을 뜻하는지 한 줄로 정리한다.

과제 3 — 우리 팀 Swagger 점검표 만들기 (5분)

지금 다니는(또는 목표로 하는) 회사의 API 문서를 떠올리며, Swagger 화면에서 QA가 확인해야 할 항목 5개 를 체크리스트로 적는다. 최소한 서버 주소 확인, 필수 필드 표시, 에러 응답 정의, enum 값 목록, 인증 방식 네 가지는 포함되어야 한다.

자가 체크리스트

  • OpenAPI(규격)와 Swagger UI(화면)의 차이를 한 문장으로 설명할 수 있다
  • Try it out → 값 입력 → Execute → 결과 확인 흐름을 도움 없이 수행할 수 있다
  • 자물쇠 아이콘이 뜻하는 바를 알고 Authorize로 토큰을 등록할 수 있다
  • bearer 방식에서 Bearer 접두어를 직접 넣으면 안 되는 이유를 말할 수 있다
  • Execute 후 나오는 curl 명령을 결함 리포트에 활용할 수 있다
  • 200 응답만 보고 통과로 처리하지 않고 값·헤더·시간까지 확인한다

흔한 실수

  • 서버 주소를 확인하지 않고 Execute 한다. Swagger UI의 실행은 실제 호출이다. 운영 서버가 선택된 상태에서 POST·DELETE를 눌러 실데이터를 만들거나 지우는 사고가 신입 시기에 실제로 발생한다. 쓰기 요청 전에는 반드시 상단 서버 드롭다운을 본다.
  • 토큰 입력칸에 Bearer 를 함께 붙여 넣는다. http/bearer 방식은 접두어가 자동이라 Bearer Bearer ...가 되어 401이 난다. 반대로 apiKey 방식에서는 필요한 접두어를 빼먹어 또 401이 난다.
  • 401을 전부 "서버 오류"로 보고한다. 대개는 토큰 만료이거나 권한 부족(403과 구분)이다. 만료 시각과 계정 권한을 먼저 확인한다.
  • Failed to fetch를 API 장애로 오해한다. Swagger UI가 API와 다른 도메인에 떠 있을 때 브라우저의 CORS 정책에 막히면 이 메시지가 뜬다. 서버는 멀쩡한데 브라우저가 막은 것 이므로, 같은 요청을 curl로 보내보면 성공한다 — 이 대조가 곧 원인 분리 근거다.
  • 문서에 없는 필드를 테스트하지 않는다. Swagger에 안 적혔다고 서버가 안 받는 건 아니다. 문서에 없는 필드를 실어 보냈을 때 무시되는지 에러인지 저장되는지는 별도의 테스트 대상이다.
  • Schemas 섹션을 건너뛴다. 필수 여부·타입·enum·최댓값이 모두 거기 있다. 테스트 데이터 설계의 재료를 통째로 버리는 셈이다.

참고 자료

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

OpenAPI — 오픈에이피아이 명세
창구가 어떤 주소로 무엇을 받고 무엇을 돌려주는지 정해진 형식으로 적어 둔 문서.
UI — 사용자 인터페이스
사람이 직접 보고 누르는 부분 — 화면, 버튼, 입력창.
QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.
API — 응용 프로그램 인터페이스
프로그램끼리 주고받는 창구. 사람이 화면 버튼을 누르는 대신, 프로그램이 정해진 주소로 요청을 보내 답을 받는다.
JSON — 제이슨
프로그램끼리 값을 주고받을 때 쓰는 글자 형식. 괄호와 따옴표로 이름과 값을 짝지어 적는다.
HTTP — 하이퍼텍스트 전송 규약
웹에서 요청과 응답을 주고받는 약속. "무엇을 달라"고 보내면 "여기 있다" 또는 "그런 건 없다"가 돌아온다.
URL — 인터넷 주소
웹에서 무언가의 위치를 가리키는 주소 한 줄.
CORS — 교차 출처 자원 공유
웹 화면이 다른 주소의 창구를 부를 수 있는지를 정하는 규칙. 허용되지 않으면 브라우저가 막는다.

용어집 전체 보기

이 레슨의 실습

실습은 별도 저장소에서 진행합니다. 새 탭으로 열립니다.