나처럼 혼자 공부하는 사람들의 시간 낭비를 막기 위해 글 씁니다.
server는 graphene-django를 이용하였고,
clinet는 apollo-boost를 이용하였다.
먼저 server쪽은
https://github.com/lmcgartland/graphene-file-upload 설치하고,
mutation을 다음과 같이 작성하였다.
from graphene_file_upload.scalars import Upload
class UploadMutation(graphene.Mutation):
class Arguments:
image = Upload(required=True)
success = graphene.Boolean()
def mutate(self, info, image, **kwargs):
print(image[0])
return UploadMutation(success=True)
그리고 url을 다음과 같이 설정하였다.
from graphene_file_upload.django import FileUploadGraphQLView
urlpatterns = [
url(r'^graphql', FileUploadGraphQLView.as_view(graphiql=True)),
]
그리고 client 쪽은
https://github.com/jaydenseric/apollo-upload-client
설치를 하고, link부분을 createUploadLink를 이용하였다.
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { resolvers } from "./LocalState";
import { setContext } from "apollo-link-context";
import { createUploadLink } from "apollo-upload-client";
const cache = new InMemoryCache();
const link = createUploadLink({
uri: "http://127.0.0.1:8000/graphql"
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem("jwt");
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `JWT ${token}` : ""
}
};
});
const client = new ApolloClient({
link: authLink.concat(link),
cache,
resolvers
});
cache.writeData({
data: {
isLoggedIn: Boolean(localStorage.getItem("jwt")) || false
}
});
export default client;
파일 올리는 페이지를 다음과 같이 작성하였다.
import React, { useCallback } from "react";
import { useMutation } from "react-apollo-hooks";
import { Image_Upload } from "./NewQueries";
export default () => {
const [ImageMutation, { loading, data, error }] = useCallback(
useMutation(Image_Upload),
[]
);
const handleChange = async e => {
const image = e.target.files;
console.log(image);
const { data } = await ImageMutation({ variables: { image } });
console.log(data);
};
return (
<div align="center" style={{ marginTop: "10%" }}>
<label htmlFor="upload-button">
<h5>Upload your photo</h5>
</label>
<input
type="file"
id="upload-button"
style={{ display: "none" }}
onChange={handleChange}
/>
</div>
);
};
mutation은 다음과 같이 작성하였다.
export const Image_Upload = gql`
mutation ImageSelf($image: Upload) {
imageSelf(image: $image) {
ok
error
}
}
`;
그리고 결과물은 다음과 같이 파일 이름이 프린트 되는 것을 확인할수 있었다.