#file-upload #graphql #apollo #apollo-server #apollostack
#загрузка файла #graphql #apollo #apollo-server #apollostack
Вопрос:
Я пытался решить проблему, но я не понимаю, почему файл загружается, но его размер равен 0 КБ. Я вижу этот код в руководстве, но он работает над этим руководством, но у меня не работает
const { ApolloServer, gql } = require('apollo-server');
const path = require('path');
const fs = require('fs');
const typeDefs = gql`
type File {
url: String!
}
type Query {
hello: String!
}
type Mutation {
fileUpload(file: Upload!): File!
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
Mutation: {
fileUpload: async (_, { file }) => {
const { createReadStream, filename, mimetype, encoding } = await file;
const stream = createReadStream();
const pathName = path.join(__dirname, `/public/images/${filename}`);
await stream.pipe(fs.createWriteStream(pathName));
return {
url: `http://localhost:4000/images/${filename}`,
};
},
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
затем, когда я загружаю файл, он загружается, но файл имеет размер 0 КБ
Ответ №1:
Что происходит, так это то, что распознаватель возвращается до того, как файл был загружен, в результате чего сервер отвечает до того, как клиент завершил загрузку. Вам нужно пообещать и дождаться событий потока загрузки файла в распознавателе.
Вот пример:
В вашем случае:
const resolvers = {
Query: {
hello: () => "Hello world!",
},
Mutation: {
fileUpload: async (_, { file }) => {
const { createReadStream, filename } = await file;
const stream = createReadStream();
const path = path.join(__dirname, `/public/images/${filename}`);
// Store the file in the filesystem.
await new Promise((resolve, reject) => {
// Create a stream to which the upload will be written.
const writeStream = createWriteStream(path);
// When the upload is fully written, resolve the promise.
writeStream.on("finish", resolve);
// If there's an error writing the file, remove the partially written
// file and reject the promise.
writeStream.on("error", (error) => {
unlink(path, () => {
reject(error);
});
});
// In Node.js <= v13, errors are not automatically propagated between
// piped streams. If there is an error receiving the upload, destroy the
// write stream with the corresponding error.
stream.on("error", (error) => writeStream.destroy(error));
// Pipe the upload into the write stream.
stream.pipe(writeStream);
});
return {
url: `http://localhost:4000/images/${filename}`,
};
},
},
};
Обратите внимание, что, вероятно, не стоит использовать такое имя файла для хранения загруженных файлов, поскольку будущие загрузки с тем же именем файла будут перезаписывать более ранние. Я не совсем уверен, что произойдет, если два файла с одинаковым именем будут загружены одновременно двумя клиентами.