I want to store all the API URLs in one place i.e in JSON file I want to use that JSON file through out my application.
i) what is the best location to keep the JSON file. ii) How to use the URLs in the Type script file
i would store the base url in the environment.ts
export const environment = {
production: false,
baseUrl: 'http://example.com/api'
};
and for the api URLs i would create an enum:
export enum ApiPaths {
Auth = '/auth',
Foo = '/foo',
Bar = '/bar'
}
And then use it in the service:
import { environment } from '../environments/environment';
import { ApiPaths } from '../enums/api-paths';
@Injectable()
export class FooService {
baseUrl = environment.baseUrl;
constructor(private httpClient: HttpClient) { }
getAll() {
let url = `${this.baseUrl}/${ApiPaths.Foo}/all`;
return this.httpClient.get<JSON>(url);
}
}
The other answers provided give great ways to store and access the base url, I personally store it in the environment.ts and insert into requests from an HttpInterceptor.
What I want to try to address in your question is managing the endpoints after the base url. This is something I would love to see a better solution to, but it's what I use at the moment.
In each Angular service that makes http calls to the API, I have a property like so:
private readonly API_ROUTES = {
getUser: (userId: string) => `/user/${userId}`
}
This is applicable to my method of passing arguments, if you use query parameters then you can adjust this to handle that.
The corresponding method can then use this:
public getUser(userId: string): Observable<User> {
return this.http.get<User>(this.API_ROUTES.getUser(userId));
}
full example class:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class UserService {
private readonly API_ROUTES = {
getUser: (userId: string) => `/user/${userId}`
}
constructor(private http: HttpClient) { }
public getUser(userId: string): Observable<User> {
return this.http.get<User>(this.API_ROUTES.getUser(userId));
}
}
This could obviously then be extracted further to have all the API routes in one file somewhere, as someone else suggested, it could just be api-routes.ts.
I hope someone else perhaps better patterns as I feel this isn't the best solution.
In our project we made different environment files for development , production, staging Like
environment.dev.ts
environment.staging.ts
environment.prod.ts
we used package.json script to take which api url need to be loaded
"scripts": {
"ng": "ng",
"start:dev": "ng build --prod -c=dev",
"start:qa": "ng build --prod -c=qa",
}
so it will load required api
example service file
import { Injectable } from '@angular/core';
import { AuthService } from 'src/app/auth.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class NetworkService {
private apiUrl: string = environment.BASE_URI;
options;
constructor(private authService: AuthService, private http: HttpClient) {}
updateNetwork(formValue) {
this.authService.loadToken();
const headers = new HttpHeaders().set(
'Authorization',
`Bearer ${this.authService.authToken}`
);
formValue.nor_id = this.authService.getNorId();
return this.http.post(`${this.apiUrl}/recipe/network`, formValue, {
headers
});
}
}