I have a Serverless (AWS) application written in NodeJS with exposed GraphQL endpoint and Upload mutation for image upload to S3 bucket.
GraphQL lambda is defined as follows
graphql:
handler: src/functions/graphql/graphql.handler
name: ${self:provider.stackName}-graphql
events:
- http:
method: POST
path: /graphql
GraphQL lambda is basically this
const server = new ApolloServer({
typeDefs,
resolvers,
});
export const handler = server.createHandler();
I have an upload
mutation defined
type Mutation {
uploadPhoto(file: Upload!, location: String): String!
}
And resolver looks like this
public async uploadPhoto(
parent: any,
params: { file: any; location: string }
): Promise<string> {
const file = await params.file;
const { createReadStream, filename, mimetype } = file;
const { ext } = parse(filename);
const uploadParams: S3.Types.PutObjectRequest = {
Bucket: process.env.PHOTO_BUCKET,
Key: `${params.location}/${randomNumber}${ext}`,
ContentType: mimetype,
Body: createReadStream(),
ContentEncoding: "base64",
ACL: "public-read",
};
try {
console.log("upload params", uploadParams);
const sendData = await this.s3bucket.upload(uploadParams).promise();
console.log(sendData);
return sendData.Location;
} catch (error) {
console.log("error uploading file", error);
return error.message;
}
}
Also to enable API Gateway to accept binary data I've installed
custom:
apigwBinary:
types:
- image/jpeg
- image/jpg
- image/png
plugins:
- serverless-apigw-binary
Still, after all this, I can upload .txt
files for instance, but images just look something like this https://cutt.ly/cg7zA6O so like an empty file. Content-type is ok, file size is also ok, but the image is corrupted.
My guess would be something about API Gateway is wrong, but I'm not 100% sure