How to make backend as a bridge between external url and frontend for retrieving files?

84 views Asked by At

I am trying to get a .pbf file from a map server. (but the question expands to pdf, jpg or csv) I wanna obtain that .pbf file and return it in a GET request.

The file comes from a private server: http:XXX.XXX.XXX.XXX/geometrictiles/${source.layername}/{z}/{x}/{y}.pbf

And want to return the exact same file to a get API in mi backend, like: http://localhost:3001/geometrictiles/${source.layername}/{z}/{x}/{y}.pbf

So to use my backend as a bridge between mi react app, and the geometrictiles server.

I generated and endpoint in my controller like:

` @Get('/geoserver')
  async getGeoTiles(){
    const data = await this.geomService.getPBF('layername',11,585,783);
    // const file = createReadStream(join(stringdata, 'package.json'));
    // return 
    // new StreamableFile(file);
    return stringdata;
  }`

And in my service: 
`async getPBF (layername, z, x, y){
// just using a json route in order to test any file
    return this.httpService
    //here should be this URL, but for testing reasons
    //http:XXX.XXX.XXX.XXX/geometrictiles/${source.layername}/{z}/{x}/{y}.pbf
    .get('https://api.coindesk.com/v1/bpi/currentprice.json')
    .pipe(
      map((res) => {
        // console.log('res', res);
        return res.data;
      })
    )
    .pipe(
      catchError(() => {
        throw new ForbiddenException('API not available');
      }),
    );
  }`


But this is not returning the file json, csv nor PBF as I need.

How is this is done?

1

There are 1 answers

0
BioStunt On BEST ANSWER

To get file using HttpService you should inject response in getGeoTiles method and write result of HttpService GET method to it response. Also, you should write 'Content-Disposition' header to response object.
Here's example of this logic to retreive file from specific url:

@Controller()
export class AppController {
  constructor(private readonly httpSerivce: HttpService) {}

  @Get('/geoserver')
  async getGeoTiles(@Res() response: Response) {
    const { data } = await firstValueFrom(
      this.httpSerivce
        .get<ArrayBuffer>('https://api.coindesk.com/v1/bpi/currentprice.json', {
          // get the content as ArrayBuffer
          responseType: 'arraybuffer',
        })
        .pipe(
          catchError(() => {
            throw new ForbiddenException('API not available');
          }),
        ),
    );
    response.setHeader(
      'Content-Disposition',
      // Here write filename instead of 'currentprice.json'
      `attachment; filename=${encodeURI('currentprice.json')}`,
    );
    // write content to response object
    response.write(data);
    // finalize
    response.end();
  }
}