はじめに
Apollo Client
からApollo Server
にGraphQLでファイルをアップロードするにあたり、必要だった知識をメモしておきます。なお、ファイルのダウンロードに関しては、base64形式等の文字列をフロントに返すといったやり方もあるようですが、素直にRESTのエンドポイントで返す形にしました。
Apollo Client 側
apollo-upload-clientというミドルウェアをApolloLinkに追加(この記事を書いた時点ではApollo Clientとの型の整合性が取れておらず、 //@ts-ignore
する必要がありました)
const client = new ApolloClient({
cache: new InMemoryCache(),
//@ts-ignore
link: createUploadLink({
uri: "http://localhost:4000",
}),
});
onChangeイベントで
<input type="file" onChange={onChange}>
mutationリクエスト
const UPLOAD_FILE = gql`
mutation($file: Upload!) {
uploadFile(file: $file) {
success
}
}
`;
Apollo Server 側
第2引数の file
に、アップロードされたファイルに関するオブジェクトが渡ってくるので、その中のcreateReadStream
でファイルのStreamオブジェクトを取得します。その後、aws-sdkを使ってS3にそのまま流し込んだり、CSVのファイルをjson形式に展開するのであればcsvtojsonを使うなど、必要な処理に進みます。
async uploadFileResolver (
parent,
{ file } : { file: Promise<FileUpload> }
) : Promise<UploadFileResponse> {
const { createReadStream, filename, mimetype, encoding } = await file;
// createReadStream()でファイルのStreamが取得できる
}
内部で使われているgraphql-uploadのFileUpload
の型がこちら
export interface FileUpload {
filename: string;
mimetype: string;
encoding: string;
createReadStream(): ReadStream;
}
ファイルのmaxサイズを指定したい場合は
const server = new ApolloServer({
typeDefs,
resolvers,
uploads: {
maxFileSize: 10000,
},
});
Codegen
Apollo Serverが自動的に追加してくれるので、スキーマファイルに scalar Upload
を記述する必要はないのですが、graphql-code-generatorを使っている場合は設定ファイルに scalar Upload
を追加する必要があります。
まとめ
今回はApollo ClientからApollo Serverへファイルのアップロードをする際に必要だった知識をまとめました。