Home > front end >  Compose request URL in backend javascript/typescript
Compose request URL in backend javascript/typescript

Time:02-26

Is there any way to compose the request URL somehow without if-else structure?

I'm trying to build a URL for the request to another service. There are 5 parameters, 1 parameter is obligatory, while the other 4, are optional.

Example: https://web-site.com/v1/assets?author=${id}&category=cat&page=1&per-page=1&sort=abc

author -- is the obligatory parameter. Other parameters can be passed independently.

Examples:

https://web-site.com/v1/assets?author=${id}&category=cat&page=1&per-page=1&sort=abc

https://web-site.com/v1/assets?author=${id}&per-page=1&sort=abc

https://web-site.com/v1/assets?author=${id}&sort=abc

https://web-site.com/v1/assets?author=${id}&category=cat&sort=abc

https://web-site.com/v1/assets?author=${id}&category=cat

I'm trying it build the URL in this way:

import { QueryDto } from '../types/dtos/query.dto'

export function urlComposer(id: string, query: QueryDto) {
  if (
    query.author != undefined &&
    query.category != undefined &&
    query.page != undefined &&
    query.perPage != undefined &&
    query.sort != undefined) {
    return`https://web-site.com/v1/assets?author=${id}&category=${query.category}&page=${query.page}&per-page=${query.perPage}&sort=${query.sort}`
  } else if (
    query.author != undefined &&
    query.category != undefined &&
    query.page != undefined &&
    query.perPage != undefined
) {
    return`https://web-site.com/v1/assets?author=${id}&category=${query.category}&page=${query.page}&per-page=${query.perPage}`
  } else if (
    query.author != undefined &&
    query.category != undefined &&
    query.page != undefined
  ) {
    return`https://web-site.com/v1/assets?author=${id}&category=${query.category}&page=${query.page}`
  } else if (
    query.author != undefined &&
    query.category != undefined
  ) {
    return`https://web-site.com/v1/assets?author=${id}&category=${query.category}`
  } else if (
    query.author != undefined &&
    query.sort != undefined
  ) {
    return`https://web-site.com/v1/assets?author=${id}&sort=${query.sort}`
  } else {
    return`https://web-site.com/v1/assets?author=${id}`
  }
}

QueryDto.ts

import { ApiProperty } from '@nestjs/swagger'

export class QueryDto {
  @ApiProperty()
  author: string
  @ApiProperty({required: false})
  category?: string
  @ApiProperty({required: false})
  page?: number
  @ApiProperty({required: false})
  perPage?: number
  @ApiProperty({required: false})
  sort?: string
}

I believe that exists a simpler way to complete such URL in runtime, do you have any references or your own solution?

CodePudding user response:

Sure, you need to get the key/value pairs from the input object using Object.entries(), filter the resulting array depending on whether there is a value, then convert it into the querystring. Like this:

class QueryDto {
  author?: string
  category?: string
  page?: number
  perPage?: number
  sort?: string
}

function urlComposer(id: string, query: QueryDto) {
  const queryString = Object.entries({ id, ...query })
                            .filter(([,value]) => value)
                            .map(([key, value]) => `${key}=${value}`)
                            .join('&')
  
  return `https://web-site.com/v1/assets?${queryString}`
}

const result = urlComposer('foo', {
  author: 'me',
  category: 'books'
})

console.log(result) // https://web-site.com/v1/assets?id=foo&author=me&category=books"
  • Related