Skip to content

Commit

Permalink
feat: remove all static methods and automatically resolve base url
Browse files Browse the repository at this point in the history
Base url is now automatically resolved after first call to any api endpoint.
Static methods to resolve base url have been removed.

BREAKING CHANGE: Static methods to resolve base url have been removed
  • Loading branch information
ivandotv committed Jun 16, 2021
1 parent 1854206 commit bbd0501
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 234 deletions.
29 changes: 0 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,6 @@ const api = new RadioBrowserApi('My Radio App')
await api.getStationsBy(StationSearchType.byTag, 'jazz')
```

After you instantiate the class, you can get the list of **available API servers** (I know, weird right?). Essentially the underlying API URL's can change and the author has two to three servers always running. Something like:
`https://fr1.api.radio-browser.info` or `https://de1.api.radio-browser.info`
This step is not mandatory because the class has one of the servers hardcoded, but If you get errors that service is not available, you can query for available servers, before actually using the API.

```ts
const api = new RadioBrowserApi('My Radio App')

await api.resolveBaseUrl() // use first result

// or

// result is { ip: string; name: string }[]
const result = await api.resolveBaseUrl()
//pick one of the results
api.setBaseUrl(result[1])
```

You can also use class static methods to set the base URL for all current and future class instances.

```ts
await RadioBrowserApi.resolveBaseUrl()

//or
const result = await RadioBrowserApi.resolveBaseUrl()

// result is { ip: string; name: string }[]
RadioBrowserApi.setBaseUrl(result[0])
```

### Querying the API

There are a lot of methods you can use to query the API.
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
"api:extract": "api-extractor run --local --verbose --typescript-compiler-folder node_modules/typescript",
"test": "cross-env BABEL_ENV=test jest --verbose --coverage --no-cache",
"test:watch": "cross-env BABEL_ENV=test jest --watch",
"test:ci": "npm run type-check && jest --runInBand --ci --reporters=default --reporters=jest-junit --coverage --coverageDirectory=coverage",
"type-check": "tsc -p tsconfig.check-types.json",
"type-check:watch": "npm run type-check -- --watch",
"test:ci": "npm run type:check && jest --runInBand --ci --reporters=default --reporters=jest-junit --coverage --coverageDirectory=coverage",
"type:check": "tsc -p tsconfig.check-types.json",
"type:check:watch": "npm run type:check -- --watch",
"build:types": "del dist/types && tsc -p tsconfig.build-types.json",
"build:browser": "del dist/unpkg && rollup -c",
"build:cjs": "del dist/cjs && cross-env BABEL_ENV=cjs babel src --out-dir dist/cjs --extensions \".ts,.tsx,js,jsx\" --source-maps --verbose",
Expand Down
79 changes: 23 additions & 56 deletions src/radioBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
* @public
*/
export class RadioBrowserApi {
protected static baseUrl: string = 'https://fr1.api.radio-browser.info/json'
static version = __VERSION__

protected baseUrl: string | undefined

Expand All @@ -37,60 +37,29 @@ export class RadioBrowserApi {
}

/**
* Resolves static API base url this will be the default for all class instances.
* Resolves API base url this will be the default for all class instances.
* @param autoSet - Automatically set first resolved base url
* @param config- Fetch configuration
* @returns Array of objects with the ip and name of the api server
*/
static async resolveBaseUrl(
autoSet = true,
async resolveBaseUrl(
config: RequestInit = {}
): Promise<{ ip: string; name: string }[]> {
let result: { ip: string; name: string }[]

const response = await fetch(
'https:https://all.api.radio-browser.info/json/servers',
'http:https://all.api.radio-browser.info/json/servers',
config
)
if (response.ok) {
result = await response.json()
if (autoSet) {
RadioBrowserApi.baseUrl = `https://${result[0].name}`
}

return result
} else {
throw response
}
}

/**
* Resolves API base url for this class instance only
* @param autoSet - Automatically set first resolved base url
* @param config- Fetch configuration
* @returns Array of objects with the ip and name of the api server
*/
async resolveBaseUrl(
autoSet = true,
config: RequestInit = {}
): Promise<{ ip: string; name: string }[]> {
const result = await RadioBrowserApi.resolveBaseUrl(false, config)

if (autoSet) {
this.baseUrl = `https://${result[0].name}`
}

return result
}

/**
* Sets static base url for all api calls
* @param url - Url to the api server
*/
static setBaseUrl(url: string): void {
RadioBrowserApi.baseUrl = url
}

/**
* Sets base url for all api calls
* @param url - Url to the api server
Expand All @@ -100,19 +69,11 @@ export class RadioBrowserApi {
}

/**
* Get current base url
* Get current base url
* @returns Base url
*/
getBaseUrl(): string {
return this.baseUrl || RadioBrowserApi.baseUrl
}

/**
* Get current static base url
* @returns Base url
*/
static getBaseUrl(): string {
return RadioBrowserApi.baseUrl
getBaseUrl(): string | undefined {
return this.baseUrl
}

/**
Expand Down Expand Up @@ -521,7 +482,7 @@ export class RadioBrowserApi {

const queryParams = queryCopy ? this.createQueryParams(queryCopy) : ''

return `${this.getBaseUrl()}/${endPoint}${search}${queryParams}`
return `${endPoint}${search}${queryParams}`
}

/**
Expand All @@ -534,16 +495,22 @@ export class RadioBrowserApi {
url: string,
fetchConfig: RequestInit = {}
): Promise<T> {
// manual merge deep
const headers = Object.assign(
{},
this.fetchConfig.headers,
fetchConfig.headers
)
const finalConfig = Object.assign({}, this.fetchConfig, fetchConfig)
finalConfig.headers = headers
const finalConfig = {
...this.fetchConfig,
...fetchConfig,
headers: {
...this.fetchConfig.headers,
...fetchConfig.headers
}
}

if (!this.baseUrl) {
const results = await this.resolveBaseUrl()
const random = Math.floor(Math.random() * results.length)
this.baseUrl = `https://${results[random].name}`
}

const response = await fetch(url, finalConfig)
const response = await fetch(`${this.baseUrl}/json/${url}`, finalConfig)

if (response.ok) {
return response.json()
Expand Down
Loading

0 comments on commit bbd0501

Please sign in to comment.