graphql-server-express-upload icon indicating copy to clipboard operation
graphql-server-express-upload copied to clipboard

[Meteor + Apollo] get blob url instead file

Open nguyenhose opened this issue 8 years ago • 8 comments

hi, I'm try to use this package to upload a file following instruction, but I got a blob url instead file. Here is my code: in server.js:

 {...}
import graphqlExpressUpload from 'graphql-server-express-upload'
import multer from "multer";

//used your interface package when create apollo server
import { createApolloServer } from 'meteor/apollo';

const WS_PORT =  8083;

const schema = makeExecutableSchema({
  typeDefs:Schema,
  resolvers:resolveFunctions,
});

createApolloServer({
  schema,
},{ graphiql:true});

const httpServer = createServer((request, response) => {
  response.writeHead(404);
  response.end();
});

httpServer.listen(WS_PORT);
const server = new SubscriptionServer({ subscriptionManager }, httpServer);

const app = express();

const storage = multer.diskStorage({
    destination: function (req, file, callback) {
        callback(null, 'uploads');
    },
    filename: function (req, file, callback) {
        console.log(file);
        var filename = file.originalname;
        var fileExtension = filename.split(".")[1];
        callback(null, Date.now() + "." + fileExtension);
    }
});

const upload = multer({
    storage: storage
});

app.use('/graphql',
    upload.array('files'),
    bodyParser.json(),
    graphqlExpressUpload({ endpointURL: '/graphql' }), // after multer and before graphqlExpress
    graphqlExpress((req) => {
        console.log('req', req);
      return {
        schema,
        context: {}
      }
    })
);

app.use('/graphiql', graphiqlExpress({
  endpointURL: '/graphql',
}));

in resolver.js

async uploadProfilePicture(root, { id, files }, context) {

           //the result of files was like [ { preview: 'blob:http://localhost:3000/8d38f565-7846' } ] }

            console.log('uploadProfilePicture', { id, files })

            return uploadProfilePicture(id, files);
        },

in the result I got a blob url like { preview: 'blob:http://localhost:3000/8d38f565-7846' } Please help.

nguyenhose avatar Jan 16 '17 04:01 nguyenhose

Hmm ... I'm not sure that I understand what your problem is ... Is file uploaded successfully? Can you view http://localhost:3000/8d38f565-7846? Can you post Request Payload from the upload mutation? What does uploadProfilePicture() return?

HriBB avatar Jan 16 '17 15:01 HriBB

function uploadProfilePicture() : Boolean

the problem is I upload a file with attributes

file {
  lastModified: 1478153157000
  lastModifiedDate: Thu Nov 03 2016 13:05:57 GMT+0700 (ICT)
  name: "14590413_698257190343797_6999820439999271573_n.jpg"
  preview: "blob:http://localhost:3000/fca57484-807b-4e3d-9905-ea036689f3f6"
  size: 78435
  type: "image/jpeg"
  webkitRelativePath: ""
}

but only got

{ preview: 'blob:http://localhost:3000/fca57484-807b-4e3d-9905-ea036689f3f6' }

what do you think ?

nguyenhose avatar Jan 17 '17 02:01 nguyenhose

@nguyenhose I also see the same thing when I use a react component like react-dropzone. How are you selecting the file?

edited When I use the standard html input type = file it seems to work

jcampb avatar Jan 24 '17 21:01 jcampb

@jcampb yes, I am using react-dropzone, too !!! Maybe it's the problem.

nguyenhose avatar Jan 25 '17 05:01 nguyenhose

So if I understand correctly, you don't receive any file data on the server? I'm not sure what react-dropzone does, but it might be related to this issue? Only FileList is supported ATM, take a look at this line.

@nguyenhose is this Request Payload or a response from the server?

file {
  lastModified: 1478153157000
  lastModifiedDate: Thu Nov 03 2016 13:05:57 GMT+0700 (ICT)
  name: "14590413_698257190343797_6999820439999271573_n.jpg"
  preview: "blob:http://localhost:3000/fca57484-807b-4e3d-9905-ea036689f3f6"
  size: 78435
  type: "image/jpeg"
  webkitRelativePath: ""
}

This is how my Request Payload looks like

------WebKitFormBoundaryCnMBmtPehed8zzBH
Content-Disposition: form-data; name="files"; filename="1461702618-sun-bun-hair.png"
Content-Type: image/png


------WebKitFormBoundaryCnMBmtPehed8zzBH
Content-Disposition: form-data; name="operationName"

addSalonResourcePicture
------WebKitFormBoundaryCnMBmtPehed8zzBH
Content-Disposition: form-data; name="query"

mutation addSalonResourcePicture($id: Int!, $files: [UploadedFile!]!) {
  addSalonResourcePicture(id: $id, files: $files) {
    id
    url
    thumb
    square
    small
    medium
    large
    full
    __typename
  }
}

------WebKitFormBoundaryCnMBmtPehed8zzBH
Content-Disposition: form-data; name="variables"

{"id":9}
------WebKitFormBoundaryCnMBmtPehed8zzBH--

HriBB avatar Jan 25 '17 09:01 HriBB

@HriBB any update on this? I know I said I'd help a while back but I've been super busy at work. Are we still only supporting FileList objects? It would be nice if we provided some sort of casting function and presented blobs rather than FileLists

thebigredgeek avatar Feb 22 '17 05:02 thebigredgeek

@thebigredgeek sorry, I am on vacation in Turkey ATM. I come back on March 5th, and we can fix/support this.

HriBB avatar Feb 23 '17 09:02 HriBB

@thebigredgeek I have fairly recently published an alternative you might find easier to setup (no Multer setup needed) and a little more flexible: apollo-upload-server. It does not provide files to the resolver as blobs from memory (I did look into that at first), but it does allow you to intuitively work with either a single File, a File array, or a FileList.

I will be actively improving apollo-upload-server and apollo-upload-client for as long as Apollo does not support uploads natively, as I am using both in two fairly large projects.

jaydenseric avatar Mar 19 '17 13:03 jaydenseric