Graphql 파일 업로드

제리님·2019년 6월 27일
11
post-thumbnail

이전에 Graphql을 이용하여 파일을 업로드 하는데 어려움이 있어 Restful API를 사용하여 별도의 서버를 만들어 파일업로드를 하였는데, 이번에 나중을 생각하여 파일업로드가 가능한 grahpql서버 보일러 플레이트를 만들고 싶어졌습니다.
공식문서와 다른분의 샘플을 보고 개인적으로 편한 방법으로 바꾸어 만들었습니다.

공식문서
graphql-upload : https://www.npmjs.com/package/graphql-upload
graphql-upload-client : https://github.com/jaydenseric/apollo-upload-client
[참고] : graphql-yoga/file-upload : https://github.com/prisma/graphql-yoga/tree/master/examples/file-upload

server

간단한 graphqlserver를 만들었습니다.

package.json

필요한 것들을 아래와 같이 설치 하였습니다.

 "dependencies": {
    "graphql-tools": "^4.0.5",
    "graphql-upload": "^8.0.7",
    "graphql-yoga": "^1.18.0",
    "merge-graphql-schemas": "^1.5.8"
  },
  "devDependencies": {
    "nodemon": "^1.19.1",
    "ts-node": "^8.3.0",
    "typescript": "^3.5.2",
    "@babel/core": "^7.4.5",
    "@babel/node": "^7.4.5",
    "@types/graphql-upload": "^8.0.0",
    "morgan": "^1.9.1"
  }

server.ts

graphql-yoga를 사용하여 graphqlserver를 생성합니다.
graphqlServer는 typeDefs와 resolvers를 필요로 합니다.

schema.ts

graphqlserver에 필요한 schema를 따로 Api폴더를 만들어 안의 graphql파일과 ts파일을 불러와 합쳐 제공합니다.


강의에서 보고 사용하는 Api폴더 내의 graphql 과 ts 파일들을 불러와 하나의 schema로 만듭니다.

singleUpload.graphql

하나의 파일을 업로드하기 위한 쿼리 입니다.

singleUpload.ts

하나의 파일을 업로드하기 위한 리졸버 입니다.

File.graphql

graphql-upload를 사용하기위해
scalar Upload upload
upload 쿼리는 필수입니다.

yarn start

서버를 실행시켜줍니다.

yarn start


Client

CRA를 사용합니다.

npx create-react-app --typescript

package.json

apollo-upload-client, graphql, graphql-tag, apollo-client,apollo-cache-inmemory를 설치합니다

"dependencies": {
    "apollo-cache-inmemory": "^1.6.2",
    "apollo-client": "^2.6.3",
    "apollo-upload-client": "^10.0.1",
    "graphql": "^14.3.1",
    "graphql-tag": "^2.10.1",
    "react": "^16.8.6",
    "react-apollo-hooks": "^0.4.5",
    "react-dom": "^16.8.6",
    "react-scripts": "3.0.1"
  },
  "devDependencies": {
    "@types/apollo-upload-client": "^8.1.2",
    "@types/jest": "24.0.15",
    "@types/node": "12.0.10",
    "@types/react": "16.8.22",
    "@types/react-dom": "16.8.4",
    "typescript": "3.5.2"
  }

client.ts

ApolloProvider에 제공할 client를 만듭니다.

grapql query

실행할 graphql query를 만듭니다.

onChagne

input의 onChange 함수를 만듭니다.

Input

type="file"과 onChange함수를 넣어줍니다.

yarn start

Test


클라이언트 콘솔

서버

서버에서 파일을 잘받았습니다.

서버: https://github.com/jerrynim/gql-upload-sample
클라이언트 : https://github.com/jerrynim/gql-upload-client-sample


요약 :개인적으로 나중에 사용할 graphql-upload boilerplate를 만들었다.
후기 : 이걸 설명하고 정리하면서 써야하는데 글쓰는게 힘들고 잘못된 정보를 쓸가봐 함부로 못쓰겠네요 🤣

profile
Basic in the end👻

3개의 댓글

comment-user-thumbnail
2019년 12월 31일

감사합니다 ^^

답글 달기
comment-user-thumbnail
2020년 7월 18일

진짜 돌아버릴거 같아요... 클라이언트에서 글쓴이님께서 해본 방식으로 하고 또 이런식으로 해봤는데
const onChange = async ({
target: {
validity,
files: [file],
},
}) => {
if (validity.valid) {
console.log("file : ", file);
const data = await editPhotoMutation({
variables: { file, id: avatarId },
});
console.log("data : ", data);
}
};
이런식으로 업로드 하고 서버에서
export default {
Mutation: {
editPhoto: async (_, args, { request, isAuthenticated }) => {
isAuthenticated(request);
console.log("args : ", args);
const {
file: { filename, mimetype, encoding },
id,
} = args;
return prisma.updateAvatar({
where: { id },
data: { filename, mimetype, encoding },
});
},
},
};

인자값으로 들어온거 콜솔로 찍어봤습니다.
args : { file: {}, id: '~~~' }
아이디 값은 잘 들어가는데 파일이 계속 빈값으로 출력되네요 ㅠㅠ 이런 이슈가 종종 있나요?

1개의 답글