web-dev-qa-db-ja.com

Angular HttpClientのbaseUrlを設定するにはどうすればよいですか?

documentation にHTTPリクエストのベースAPI URLを設定する方法が見つかりませんでした。 Angular HttpClientでこれを行うことは可能ですか?

50
Stepan Suvorov

新しいHttpClient Interceptorを使用します。

HttpInterceptor:を実装する適切なインジェクタブルを作成します

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class APIInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const apiReq = req.clone({ url: `your-api-url/${req.url}` });
    return next.handle(apiReq);
  }
}

HttpInterceptorは要求を複製し、必要に応じて変更できます。この場合、すべてのhttp要求に対してデフォルトパスを定義しました。

次の構成でHttpClientModuleを提供します:

providers: [{
      provide: HTTP_INTERCEPTORS,
      useClass: APIInterceptor,
      multi: true,
    }
  ]

これで、すべてのリクエストはyour-api-url/で始まります

71
TheUnreal

TheUnrealの非常に有用な答えに基づいて、インターセプターは、DIを介してベースURLを取得するように記述できます。

@Injectable()
export class BaseUrlInterceptor implements HttpInterceptor {

    constructor(
        @Inject('BASE_API_URL') private baseUrl: string) {
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        const apiReq = request.clone({ url: `${this.baseUrl}/${request.url}` });
        return next.handle(apiReq);
    }
}

BASE_API_URLは、アプリケーションモジュールによって提供できます。

providers: [
    { provide: "BASE_API_URL", useValue: environment.apiUrl }
]

environmentは、プロジェクトの生成時にCLIによって自動的に作成されるオブジェクトです。

export const environment = {
  production: false,
  apiUrl: "..."
}; 
22
Alexei

ベースURL withHttpClientは必ずしも必要ではありません。ドキュメントでは、同じサーバーに呼び出しを行う場合、次のように簡単です:

this.http.get('/api/items').subscribe(data => { ...

ただし、必要な場合はベースURLを指定できます。

私はそれを行うための2つの提案があります:

1。静的クラスプロパティを持つヘルパークラス。

export class HttpClientHelper{

    static baseURL: string = 'http://localhost:8080/myApp';
}


this.http.get(`${HttpClientHelper.baseURL}/api/items`);//in your service class

2。クラスプロパティを持つ基本クラスであるため、新しいサービスで拡張する必要があります。

export class BackendBaseService {

  baseURL: string = 'http://localhost:8080/myApp';

  constructor(){}

}

@Injectable()
export class ItemsService extends BackendBaseService{

  constructor(private http: HttpClient){  
    super();
  }

  public listAll(): Observable<any>{    
    return this.http.get(`${this.baseURL}/api/items`);
  }

}
5
skinny_jones

Visual Studio 2017 asp.net core webapi angularサンプルアプリケーションからの抜粋。

main.tsに以下の行を含めます

export function getBaseUrl() {
  return document.getElementsByTagName('base')[0].href;
}

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];

コンポーネント内

  constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
      this.forecasts = result;
    }, error => console.error(error));
  }

私の完全なmain.tsコードは以下のようになります

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

export function getBaseUrl() {
  return document.getElementsByTagName('base')[0].href;
}

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

私のコンポーネントコードは以下のようになります

import { Component, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'fetch-weather',
  templateUrl: './weather.component.html',
  styleUrls: ['./weather.component.scss']
})

export class WeatherComponent {
  public forecasts: WeatherForecast[];

  constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
      this.forecasts = result;
    }, error => console.error(error));
  }
}

interface WeatherForecast {
  dateFormatted: string;
  temperatureC: number;
  temperatureF: number;
  summary: string;
}

3
Moorthi Daniel

これを行うデフォルトの方法はないと思います。 HttpServiceを実行すると、デフォルトURLのプロパティを定義し、プロパティURLでhttp.getなどを呼び出すメソッドを作成できます。次に、HttpClientの代わりにHttpServiceを注入します

1
Anton Lee

構成可能なbaseUrlを持つHttpClientサブクラスを作成してみませんか?そのようにして、アプリケーションが複数のサービスと通信する必要がある場合、それぞれに異なるサブクラスを使用するか、それぞれ異なる構成で単一のサブクラスの複数のインスタンスを作成できます。

@Injectable()
export class ApiHttpClient extends HttpClient {
  public baseUrl: string;

  public constructor(handler: HttpHandler) {
    super(handler);

    // Get base url from wherever you like, or provision ApiHttpClient in your AppComponent or some other high level
    // component and set the baseUrl there.
    this.baseUrl = '/api/';
  }

  public get(url: string, options?: Object): Observable<any> {
    url = this.baseUrl + url;
    return super.get(url, options);
  }
}
0
Neutrino