Search code examples
typescriptexpressapi-design

In Nest.js, how to serve static content file/s bundled together with my JSON object in my API Response


In my Nest.js API I have a GET that must return a db row, together with (up to) 6 image files (base64 encoded), in the Response.

What I can do is this:

6 of the columns in the db contain the unique files names (the actual images are in a folder called "image-uploads"), and together with the path I can use the @Res decorator to send any one of them back e.g.

@Get('/findVehicleEntry/:id')
async findVehicleEntry(@Param('id') id: number, @Res() res) {
    const resVehicle: Vehicle = await this.vehiclesService.findVehicleEntry(id);
    if (resVehicle) {
        res.sendFile(resVehicle.photo1, { root: 'image-uploads' });
    }
}

The above successfully downloads one image file as Content-Type: "application/octet-stream"

My plan is (and what I don't know how to do is):

Firstly, get the image from the folder and into a variable, then run a base64 encode on it, then set resVehicle.photo1 equal to that base64 string, and do the same for the other 5 images, then do a res.send(resVehicle);

Something like this:

@Get('/findVehicleEntry/:id')
    async findVehicleEntry(@Param('id') id: number, @Res() res) {
    const resVehicle: Vehicle = await this.vehiclesService.findVehicleEntry(id);
    if (resVehicle) {
        let image = something.get('resVehicle.photo1', 'my/path/to/image-uploads');
        image = Buffer.from(image).toString('base64');
        resVehicle.photo1 = image;
        // do the same for the other 5 images
        res.send(resVehicle);
    }
}

This is the first time I've used Nest/Express/Node, actually this is the first API I have written so my idea/design may be totally off. Any suggestions welcome. Many thanks.

Edit: Been reading that base64 encoding of large files is not a good idea. I'm happy to drop the base64 idea, main question is how to get my db row JSON object and the 6 images into the same Response?


Solution

  • You are correct that base64 encoding of the images is not a good idea.

    The traditional solution here is: You don't push the images, you provide the image path in your json response and let the API consumer use the path to get the image.

    • keep the actual image files in a publicly available folder, not in a database. This means it should be accessible from the browser at for example yourdomain.com/images/image232.jpg
    • in your database, store the path to those images as a string (image1: "yourdomain.com/images/image232.jpg")
    • serve your json response containing the path ({make:"Toyota", image1:"yourdomain.com/images/image232.jpg"})
    • Whoever is consuming your API can then use the path to get the image.