GraphQL 파일 전송

문용필
Prisma Korea
Published in
4 min readFeb 24, 2020

일반적으로 REST API를 사용하여 JSON 형식의 데이터를 전송할 경우에는 ContentType을 application/json으로, 파일의 경우에는 multipart/form-data으로 설정합니다. 여기서 ContentType이란 HTTP에서 body에 실리는 데이터의 타입을 말하고 서버에서는 이를 확인하여 타입에 맞게 데이터를 Parsing 합니다.

GraphQL의 쿼리는 json형식을 따르기 때문에 항상 ContentType이 application/json인 요청을 해야 합니다.

curl \\
-X POST \\
-H "Content-Type: application/json" \\
--data '{ "query": "{ posts { title } }" }' \\
<https://localhost:4000/graphql>

그렇다면 GraphQL의 파일 전송은 어떻게 이루어질까요? 앞에서 말했던 것처럼 일반적인 파일은 multipart/form-data 형식을 따라 전송이 되는데 Graphql은 application/json은 받을 수밖에 없기 때문에 문제가 될 수 있습니다.

결론부터 말하자면 두 데이터 형식의 차이를 메워 줄 미들웨어가 필요합니다.이 미들웨어가 클라이언트로부터 multipart/form-data 형식의 데이터를 캐치하여 GraphQL이 이해할 수 있는 JSON 형식으로 바꾸어 전달해 주는 역할을 합니다. 다행스럽게도 이러한 미들웨어는 다음과 같은 스펙에 따라 Apollo 서버(2.0)에 구현되어 있습니다.

아래는 위 스팩에 따라 Apollo 서버에 파일을 업로드하는 예제 입니다.

curl localhost:3001/graphql \
-F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }' \
-F map='{ "0": ["variables.file"] }' \
-F 0=@a.txt

curl에서 -F 옵션은 multipart/form-data 형식으로 각각 form에 input field를 추가하는 것 을 의미합니다.

opertions에는 Graphql query,

map에는 전송되는 파일을 매핑하는 정보,

index에는 실제 파일이 들어갑니다.

실제 Apollo 파일 업로드 구현에 관한 예제는 다음 글에서 잘 다루고 있습니다.

실제 구현 후 네트워크 창을 확인해 보시면 해당 스펙에 따라 전송 되는 것을 확인해 볼 수 있습니다.

GraphQL도 결국 HTTP 통신이고 파일들도 문자로 이루어졌다는 점을 유의하면 이해하시는 데 도움이 될 것이라고 생각합니다.

요약

  • 모든 GraphQL 요청은 application/json 형식의 Post 요청으로 이루어진다.
  • 파일은 multipart/form-data 형식으로 body에 파일 데이터를 담아서 전송된다.
  • 파일을 GraphQL을 통해 전송하기 위해선 application/json 형식으로 바꿔 줄 미들웨어가 필요하고 이를 위한 스펙이 존재한다.

참고 링크

--

--