이전에 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
간단한 graphqlserver를 만들었습니다.
필요한 것들을 아래와 같이 설치 하였습니다.
"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"
}
graphql-yoga를 사용하여 graphqlserver를 생성합니다.
graphqlServer는 typeDefs와 resolvers를 필요로 합니다.
graphqlserver에 필요한 schema를 따로 Api폴더를 만들어 안의 graphql파일과 ts파일을 불러와 합쳐 제공합니다.
강의에서 보고 사용하는 Api폴더 내의 graphql 과 ts 파일들을 불러와 하나의 schema로 만듭니다.
하나의 파일을 업로드하기 위한 쿼리 입니다.
하나의 파일을 업로드하기 위한 리졸버 입니다.
graphql-upload를 사용하기위해
scalar Upload upload
upload 쿼리는 필수입니다.
서버를 실행시켜줍니다.
yarn start
CRA를 사용합니다.
npx create-react-app --typescript
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"
}
ApolloProvider에 제공할 client를 만듭니다.
실행할 graphql query를 만듭니다.
input의 onChange 함수를 만듭니다.
type="file"과 onChange함수를 넣어줍니다.
yarn start
클라이언트 콘솔
서버
서버에서 파일을 잘받았습니다.
서버: https://github.com/jerrynim/gql-upload-sample
클라이언트 : https://github.com/jerrynim/gql-upload-client-sample
요약 :개인적으로 나중에 사용할 graphql-upload boilerplate를 만들었다.
후기 : 이걸 설명하고 정리하면서 써야하는데 글쓰는게 힘들고 잘못된 정보를 쓸가봐 함부로 못쓰겠네요 🤣
진짜 돌아버릴거 같아요... 클라이언트에서 글쓴이님께서 해본 방식으로 하고 또 이런식으로 해봤는데
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: '~~~' }
아이디 값은 잘 들어가는데 파일이 계속 빈값으로 출력되네요 ㅠㅠ 이런 이슈가 종종 있나요?
감사합니다 ^^