user2534584
user2534584

Reputation: 533

NestJS - File upload to microservice

I need to upload a file to an API-Gateway. After adding some meta information, the file should be send to another (micro) service (as Content-Type: multipart/form-data). I am having some problems to build a FormData object within the API-Gateway. I do not want to persist the file on the gateway, so I am basically just trying to pass it through.

For creating the formData-object, I am using Form-Data

This is what a tried:

    // Controller
    @Post()
    @UseInterceptors(FileInterceptor('file'))
    async create(@Res() res, @UploadedFile('file') file, @Body() body: any) {
        return await this.someService.create(file);
    }
    // Service
    async create(file: any) {
        const formData = new FormData();

        formData.append('file', file);
        formData.append('key', 'value');

        const formHeaders = formData.getHeaders();

        try {
            const result = await this.httpService

                .post('http://some-other-service/import', formData , {
                    headers: {
                        ...formHeaders,
                    },
                })
                .toPromise();
            return result.data;
        } catch (e) {
            throw new BadGatewayException();
        }
    }

This results in the following error:

TypeError: source.on is not a function
at Function.DelayedStream.create (/usr/app/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
at FormData.CombinedStream.append (/usr/app/node_modules/combined-stream/lib/combined_stream.js:44:37)
at FormData.append (/usr/app/node_modules/form-data/lib/form_data.js:74:3)
at ImportService.<anonymous> (/usr/app/src/import/import.service.ts:47:18)

Upvotes: 9

Views: 4838

Answers (1)

Teppo Kauppinen
Teppo Kauppinen

Reputation: 671

This question is a bit old, but someone might benefit from this solution.

The problem is that you are passing the whole @UploadedFile object to the formData.append method. The @UploadedFile object contains the data from from the file, but also mimetype, size, fieldname ('file' in this case), originalname (the original file name), etc.

You need to pass the actual contents of the file you are trying to upload to the formData.append method.

So to make it work, use

formData.append('file', file.buffer);

//OR 
formData.append('file', file.buffer, file.originalname);

Upvotes: 6

Related Questions