붙여 넣은 curl을 읽을 수 있으면 API 조사가 빨라진다

문서나 브라우저 개발자 도구에서 복사한 curl 명령은 보통 이런 모습입니다.

curl -X POST 'https://api.example.com/v1/items?limit=10' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Alice","tags":["a","b"]}'

읽을 줄 알면 단순하지만, 옵션 조합에 따라 동작이 달라지는 지점이 몇 군데 있고, 이를 모르면 “같은 명령인데 여기서는 안 된다”를 만나게 됩니다.

주요 옵션 표

옵션의미
-X, --requestHTTP 메서드 지정(GET / POST / PUT / DELETE)
-H, --header요청 헤더 추가. 여러 번 쓸 수 있음
-d, --data요청 본문 전송. 붙이면 자동으로 POST
--data-raw-d 와 같지만 앞의 @ 를 파일 지정으로 해석하지 않음
-F, --formmultipart/form-data 로 전송(파일 업로드)
-u, --user기본 인증(user:password)
-L, --location리다이렉트(3xx) 추적
-o, --output응답을 파일로 저장
-O, --remote-nameURL 끝의 파일명으로 저장
-s, --silent진행 표시를 숨김
-S, --show-error-s 와 함께 써서 오류만은 표시
-i, --include응답 헤더도 출력에 포함
-I, --headHEAD 요청을 보내 헤더만 확인
-v, --verbose요청 헤더를 포함한 상세 내역 표시
-k, --insecure서버 인증서를 검증하지 않음
--compressed압축 전송을 요청
-b, --cookie쿠키 전송
-c, --cookie-jar받은 쿠키를 파일로 저장
-w, --write-out완료 후 %{http_code} 등의 정보를 출력

-X POST 는 대개 생략할 수 있다

-d 를 붙이면 curl은 자동으로 POST가 됩니다. 아래 두 줄은 같습니다.

curl -X POST https://api.example.com/items -d '{"a":1}'
curl https://api.example.com/items -d '{"a":1}'

문제는 반대 경우입니다. -X GET-d 를 함께 쓰면 본문이 있는 GET 요청이 되고, 프록시나 서버에 따라 무시되거나 거부됩니다. “로컬에서는 되는데 운영에서 실패”의 전형적인 원인입니다.

-d 를 여러 번 쓰면 값들이 & 로 이어집니다. 폼 전송에는 편하지만 JSON에는 치명적입니다.

# 의도와 다름: {"a":1}&{"b":2} 가 전송됨
curl -d '{"a":1}' -d '{"b":2}' https://api.example.com/items

-d@ 는 파일 읽기가 된다

-d 에 넘긴 값이 @ 로 시작하면 curl은 그 파일을 읽어 내용을 보냅니다.

curl -d @payload.json https://api.example.com/items   # 파일 내용을 전송

편리하지만 사용자명이나 이메일을 그대로 넘기면 사고가 납니다.

# 의도: 문자열 "@alice" 전송
# 실제: ./alice 파일을 찾다가 없으면 오류
curl -d '@alice' https://api.example.com/items

@ 가 포함된 값을 그대로 보내려면 --data-raw 를 쓰세요. @ 를 특별 취급하지 않습니다.

Content-Type 은 저절로 JSON이 되지 않는다

-d 를 쓰면 따로 지정하지 않는 한 Content-Type: application/x-www-form-urlencoded 가 붙습니다. JSON을 보내면서 헤더를 빠뜨리면 서버가 파싱에 실패합니다.

curl -H 'Content-Type: application/json' \
     -d '{"name":"Alice"}' https://api.example.com/items

curl 7.82 이후에는 --json 이 있어 Content-Type: application/jsonAccept: application/json 을 함께 붙여 줍니다. 다만 예전 환경에는 없으므로, 공유할 명령에는 헤더를 명시하는 편이 안전합니다.

따옴표 구분이 가장 큰 사고 요인

표기동작
'...'(작은따옴표)안의 $" 를 그대로 전달. JSON이라면 이쪽
"..."(큰따옴표)셸이 $변수 를 전개

JSON은 큰따옴표를 포함하므로 바깥쪽은 작은따옴표가 기본입니다.

# OK
curl -d '{"name":"Alice"}' https://api.example.com/items

# 셸이 안쪽 따옴표를 벗겨 본문이 깨짐
curl -d "{"name":"Alice"}" https://api.example.com/items

토큰을 환경 변수에서 넣어야 할 때는 두 가지를 의도적으로 섞습니다.

curl -H "Authorization: Bearer $TOKEN" \
     -d '{"name":"Alice"}' https://api.example.com/items

Windows 명령 프롬프트는 작은따옴표를 해석하지 않으며, PowerShell에서는 curlInvoke-WebRequest 의 별칭인 경우가 있습니다. curl.exe 를 명시하거나 WSL·Git Bash에서 실행하세요.

URL에 & 가 있으면 따옴표로 감싼다

파라미터가 여러 개인 URL을 그대로 붙여 넣으면 셸이 & 를 백그라운드 실행으로 해석해 명령이 잘립니다.

# 깨짐: limit=10 까지만 전달됨
curl https://api.example.com/items?limit=10&offset=20

# 올바름
curl 'https://api.example.com/items?limit=10&offset=20'

공백이나 비ASCII 문자가 들어간 값은 퍼센트 인코딩이 필요합니다. URL 인코딩·디코딩 으로 확인하거나, -G--data-urlencode 로 curl에게 맡길 수 있습니다.

curl -G https://api.example.com/search --data-urlencode 'q=서울 타워'

쉽게 붙이면 안 되는 두 가지

-k / --insecure 는 인증서 검증을 끕니다. 로컬에서 자체 서명 인증서를 시험할 때는 필요하지만, 오류를 없애려고 붙였다가 그대로 공유되거나 운영에 들어가는 것이 전형적인 사고입니다. 인증서 문제는 인증서 쪽에서 고치세요.

-L / --location 은 리다이렉트를 따라갑니다. 편리하지만 POST가 리다이렉트될 때 메서드와 본문의 취급이 달라질 수 있습니다. 동작을 고정하려면 --post301 --post302 --post303 으로 명시하세요.

읽은 curl을 그대로 코드로

읽어낸 curl을 애플리케이션 코드로 옮길 때 헤더와 본문을 손으로 옮겨 적는 것은 실수의 원인입니다. cURL 변환기 에 붙여 넣으면 JavaScript·Python·Go 등의 요청 코드로 변환됩니다. 따옴표 대응과 헤더 분해는 도구가 처리합니다.

보낼 JSON의 정렬과 문법 확인은 JSON 포매터, 쿼리 문자열의 내용을 보려면 URL 파라미터 → JSON 변환 이 편리합니다. 모두 브라우저 안에서 처리되므로 인증 토큰이 포함된 명령을 붙여 넣어도 외부로 전송되지 않습니다.

정리

  • -d 를 붙이면 자동으로 POST. -X GET 과 함께 쓰면 본문 있는 GET이 되어 다루기 어렵다
  • -d 값이 @ 로 시작하면 파일 읽기. 문자열로 보내려면 --data-raw
  • -d 만으로는 폼 형식. JSON이면 헤더를 명시하거나 --json(curl 7.82+)
  • JSON을 보낼 때 바깥은 작은따옴표, 변수 전개가 필요한 곳만 큰따옴표
  • URL에 & 가 있으면 따옴표로 감싼다. 값 인코딩은 -G --data-urlencode 가 안전
  • -k 는 오류를 지우는 도구가 아니며, -L 은 POST 동작을 바꿀 수 있다

자주 묻는 질문

-X POST 는 안 써도 되나요?

대개 필요 없습니다. -d-F 를 붙인 시점에 자동으로 POST가 됩니다. 다만 명시해 두면 의도가 전달되므로 공유할 명령에는 써 둘 가치가 있습니다. 피해야 할 것은 -X GET-d 의 조합으로, 본문 있는 GET이 되어 환경에 따라 무시되거나 거부됩니다.

-d--data-raw 의 차이는 무엇인가요?

값이 @ 로 시작할 때의 처리만 다릅니다. -d@ 뒤 문자열을 파일명으로 보고 내용을 읽어 보내지만, --data-raw 는 문자열 그대로 보냅니다. 이메일 주소처럼 @ 를 포함한 데이터를 보낼 때는 --data-raw 를 쓰세요.

JSON을 보냈는데 서버가 파싱하지 못합니다

-d 를 쓰면 기본 Content-Typeapplication/x-www-form-urlencoded 이므로 -H 'Content-Type: application/json' 이 필요합니다. curl 7.82 이후라면 --json 으로 헤더까지 지정할 수 있습니다.

Windows에서 명령이 동작하지 않습니다

명령 프롬프트는 작은따옴표를 해석하지 않고, PowerShell에서는 curlInvoke-WebRequest 의 별칭일 수 있습니다. curl.exe 를 명시하거나 WSL·Git Bash처럼 작은따옴표를 해석하는 셸에서 실행하세요.

인증 토큰이 든 명령을 붙여 넣어도 괜찮나요?

cURL 변환기 는 브라우저 안에서 처리가 끝나며 붙여 넣은 내용이 전송되지 않습니다. 다만 변환된 코드에는 토큰이 그대로 남으므로, 코드를 커밋하기 전에 환경 변수로 분리하는 것을 권합니다.