Angular: 인터셉터를 사용하여 아름다운 방식으로 Angular HTTPClient로 여러 API 사용
18816 단어 codequalityhttparchitectureangular
필요할 때 항상 환경 파일을 가져오고 참조하는 대신 HttpInterptor를 사용하여 올바른 백엔드 기본 URL을 추가하고 컨텍스트를 기반으로 헤더를 설정합니다. 서버 렌더에서 다른 환경을 처리하는 데 문제가 있는 경우에도 솔루션이 될 수 있습니다.
기본적으로 아이디어는 각 HTTP 요청에서 백엔드 기본 URL을 식별하기 위해 "@api-x"로 URL의 문자열 접두사를 사용하는 것입니다.
this.http.get('@api-x/specific_endpoint')
어떻게 작동합니까? 아래 가이드를 따르십시오.
1- 먼저 HttpInterceptor를 사용하여 인터셉터를 만들어야 합니다.
import { Injectable } from ‘@angular/core’;
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from ‘@angular/common/http’;
import { Observable } from ‘rxjs’;
import { environment } from ‘environments/environment’;
@Injectable()
export class ApiInterceptor implements HttpInterceptor {
constructor() { }
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// Get the request url
let requestUrl = req.url;
// if the request URL have the string prefix,
// then make the replace by the correct url
if (requestUrl.indexOf(‘@api-x’) !== -1) {
requestUrl = requestUrl.replace(‘@api-x’, environment.api);
}
// clone the http request
req = req.clone({
url: requestUrl
});
// move to next HttpClient request life cycle
return next.handle(req);
}
}
여기에서 기본적으로 요청을 수신하고 요청된 URL의 문자열 접두사 "api-x"를 환경 파일에 정의된 올바른 URL로 바꾸는 인터셉터를 만들고 있습니다.
2- 일부 응용 프로그램 모듈에 생성된 인터셉터를 추가합니다. 제공자 배열에 등록합니다.
...
imports: [
// import the http client module
HttpClientModule,
...
],
providers: [
// register the interceptor created
{
provide: HTTP_INTERCEPTORS,
useClass: ApiInterceptor,
multi: true
},
…
]
...
응용 프로그램에 SharedModule이 있는 경우 AppModule 또는 SharedModule에 등록하는 것이 좋습니다. 그러나 주의할 점은 HttpClientModule을 가져오는 동일한 모듈이나 자식 모듈에 제공해야 합니다. 왜 필요합니까? 이력서에서 의존성 주입이 Angular에서 작동하는 방식 때문입니다.
3- http 클라이언트를 가져오고 요청을 생성합니다.
...
constructor(
// import the dependency with the constructor
private http: HttpClient
) {}
getNews() {
return this.http.get(‘@api-x/specific_endpoint_to_get_news');
}
...
이제 요청 URL 매개변수에 접두사 @api-x를 사용하기만 하면 어려움 없이 요청할 수 있습니다.
그러나 더 많은 기본 지원 URL이 필요한 경우 무엇을 할 수 있습니까?
4- 접두사를 더 추가합니다.
ApiInterceptor의 구현을 수정합니다.
...
let requestUrl = req.url;
if (requestUrl.indexOf(‘@api-x’) !== -1) {
requestUrl = requestUrl.replace(‘@api-x’, environment.api);
}
//added: a new prefix "@api-y"
if (requestUrl.indexOf(‘@api-y’) !== -1) {
requestUrl = requestUrl.replace(‘@api-y’, environment.otherBackEnd);
}
...
새 API에 새 요청을 추가합니다.
...
constructor(
private http: HttpClient
) {}
getNews() {
return this.http.get('@api-x/specific_endpoint_to_get_news');
}
getDocuments() {
return this.http.get('@api-y/specific_endpoint_to_get_documents');
}
...
자, 이제 여러 API를 쉽게 사용할 수 있습니다. 하지만 헤더를 설정해야 하는 경우 어떻게 해야 할까요?
5- 컨텍스트를 기반으로 헤더를 설정합니다.
수락하도록 ApiInterceptor를 수정합니다.
...
// added: capture the token - could be a service call here
const tokenApiX = localStorage.getItem(‘tokenApiX’);
let requestUrl = req.url;
if (requestUrl.indexOf(‘@api-x’) !== -1) {
requestUrl = requestUrl.replace(‘@api-x’, environment.api);
// added: add the header
// only to request with url that contain the prefix @api-x
req = req.clone({setHeaders: {
Content-Type: 'application/json',
Access-Control-Allow-Origin: '*',
Authorization: "Bearer " + tokenApiX
}});
}
if (requestUrl.indexOf(‘@api-y’) !== -1) {
requestUrl = requestUrl.replace(‘@api-y’, environment.otherBackEnd);
}
...
각 백엔드 기본 URL에 대한 워크플로를 제어하는 방법에 따라 애플리케이션에 필요한 헤더를 특정 문자열 접두사 또는 둘 모두에 적용할 수 있습니다. 우리는 우리가 원하는 모든 것을 할 수 있습니다. 그것은 강력하다.
좋아요, 하지만 서버 렌더링 컨텍스트에서 어떻게 도움이 될까요?
6- 브라우저 또는 노드(서버)와 같은 런타임 환경에 따라 다른 백엔드 기본 URL을 처리합니다.
인터셉터를 수정합니다.
import { PLATFORM_ID, Inject } from ‘@angular/core’;
import { isPlatformBrowser} from ‘@angular/common’;
…
export class ApiInterceptor implements HttpInterceptor {
constructor(@Inject(PLATFORM_ID) platformId: string) { }
intercept(
…
if (requestUrl.indexOf(‘@api-x’) !== -1) {
// added: verification of browser context
if (isPlatformBrowser(platformId);) {
//this is only executed on the browser
requestUrl = requestUrl.replace(‘@api-x’, environment.apiExternal);
} else {
//this is only executed on the server
requestUrl = requestUrl.replace(‘@api-x’, environment.apiInternal);
}
}
…
이제 동일한 http 요청 코드로 많은 수정 없이 런타임 컨텍스트에 따라 다른 APIS 주소를 사용할 수 있습니다.
우리는 또한 API 인터셉터 구현 코드를 개선하고 리팩토링을 할 수 있지만 이것은 다른 기사의 대상입니다.
Reference
이 문제에 관하여(Angular: 인터셉터를 사용하여 아름다운 방식으로 Angular HTTPClient로 여러 API 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/leonardovff/angular-consuming-multiple-apis-with-angular-httpclient-in-a-beautiful-way-using-interceptors-3im1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)