一个Angular HttpClient 的demo

Angular HttpClient 架构和最佳实践

Angular 是一种流行的 JavaScript 前端框架,用于构建 Web 应用程序。默认情况下,Angular 提供了一个 HttpClient 模块,允许开发人员向服务器发出 HTTP 请求、获取数据并将数据发送回服务器。在本文中,我们将讨论 Angular HttpClient 模块的架构以及使用它时应遵循的最佳实践。

什么是 HttpClient?

HttpClient 是一个 Angular 模块,允许您通过简单的 API 向服务器发出 HTTP 请求。HttpClient 模块提供了执行 GET、POST、PUT、DELETE 请求等的方法。Angular 团队将其作为 Angular 2-4 版本中已弃用的 Http 模块的替代品。

HttpClient 架构

HttpClient 的架构可以分为两个主要部分:

    • @angular/common/http 命名空间:
  1. import { HttpClient } from '@angular/common/http';
    
    • HttpClient 类:
  2. constructor(private http: HttpClient) { }
    

命名@angular/common/http空间包括发出 HTTP 请求所需的所有类,例如 HttpClient、HttpHeaders、HttpParams 等。该类HttpClient提供执行实际 HTTP 请求以及处理响应的方法。

导入 HttpClient

要将 HttpClient 导入 Angular 组件,可以使用以下代码:

import { HttpClient } from '@angular/common/http';
 
@Injectable({
  providedIn: 'root'
})
export class MyService {
  constructor(private http: HttpClient) { }
 
  getData() {
    return this.http.get('http://example.com/data');
  }
}

在上面的代码中,我们HttpClient@angular/common/http命名空间导入类,然后将其注入到我们的MyService类构造函数中。这允许我们使用 来HttpClient发出 HTTP GET 请求http://example.com/data并获取数据。

将 HttpHeader 与 HttpClient 一起使用

在发出 HTTP 请求时,您还可以在请求中包含标头。该类HttpHeaders允许您为 HTTP 请求创建和设置标头:

import { HttpClient, HttpHeaders } from '@angular/common/http';
 
@Injectable({
  providedIn: 'root'
})
export class MyService {
  constructor(private http: HttpClient) { }
 
  postData(data: any) {
    const headers = new HttpHeaders({
      'Content-Type': 'application/json'
    });
 
    return this.http.post('http://example.com/data', data, { headers });
  }
}

上面的代码包含该类HttpHeaders并创建一个带有Content-Typeof的新标头application/json。然后在请求选项中设置此标头post并与数据一起发送到http://example.com/data.

使用 HttpClient 的最佳实践

现在您了解了该HttpClient模块的基础知识,让我们看一下使用它时应遵循的一些最佳实践:

始终使用 Observable 对象

该模块默认HttpClient返回一个对象。ObservableObservables 可以从组件订阅,并且可以随时间提供多个值,这与检索单个值的 Promises 不同。这为在较长时间内解析值提供了更大的灵活性。例如:

export class MyComponent implements OnInit {
  items$: Observable<any[]>;
 
  constructor(private http: HttpClient) { }
 
  ngOnInit() {
    this.items$ = this.http.get<any[]>('http://example.com/data');
  }
}

在上面的代码中,我们使用模块Observable返回的对象HttpClient并将其分配给一个名为 的属性items$,该属性可以从组件订阅。这比在延长的时间段内解析值提供了更大的灵活性。

处理错误

发出 HTTP 请求时,处理可能发生的错误很重要。这可以使用运算符来完成catchError

import { HttpClient } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
 
@Injectable({
  providedIn: 'root'
})
export class MyService {
  constructor(private http: HttpClient) { }
 
  getData() {
    return this.http.get('http://example.com/data').pipe(
      catchError(err => {
        console.error(err);
        return throwError(err);
      })
    );
  }
}

在上面的代码中,我们使用catchErrorRxJS 库提供的运算符来捕获在发出 HTTP 请求时可能发生的任何错误。然后我们将错误记录到控制台并使用throwError运算符将​​其返回。

实施缓存策略

发出重复的 HTTP 请求时,实施缓存策略可能会有所帮助。这有助于减少对服务器的请求数量并提高应用程序的性能。

实现缓存的一种方法是使用 Angular 的内置cacheInterceptor. 这可以通过创建一个新类来完成HttpCacheInterceptor

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpResponse, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
 
@Injectable()
export class HttpCacheInterceptor implements HttpInterceptor {
  private cache = new Map<string, HttpResponse<any>>();
 
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // try to retrieve a cached response
    const cachedResponse = this.cache.get(req.url);
 
    // return cached response
    if (cachedResponse) {
      return of(cachedResponse);
    }
 
    // send request to server and cache response
    return next.handle(req).pipe(
      tap(event => {
        if (event instanceof HttpResponse) {
          this.cache.set(req.url, event);
        }
      })
    );
  }
}

在上面的代码中,我们创建了一个HttpCacheInterceptor拦截 HTTP 请求和响应的新类。该cache变量是一个Map存储缓存响应的对象。该intercept方法首先检查请求的 URL 是否存在缓存响应。如果存在,则返回缓存的响应,否则将请求发送到服务器,缓存响应并返回。

测试 HttpClient 请求

在测试使用该HttpClient模块发出 HTTP 请求的组件时,模拟 HTTP 请求很重要。这可以通过提供以下的模拟实现来完成HttpClient

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;
  let httpMock: HttpTestingController;
 
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      declarations: [MyComponent]
    })
      .compileComponents();
  }));
 
  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    httpMock = TestBed.inject(HttpTestingController);
  });
 
  afterEach(() => {
    httpMock.verify();
  });
 
  it('should get data', () => {
    const mockData = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' }
    ];
 
    component.getData();
 
    const req = httpMock.expectOne('http://example.com/data');
    req.flush(mockData);
 
    expect(component.items).toEqual(mockData);
  });
});

在上面的代码中,我们为MyComponent组件创建了一个新的测试。我们首先将 导入HttpClientTestingModule到测试模块中,然后HttpClient使用HttpTestingController. 然后我们创建一个新的测试来检查该方法是否getData从服务器获取数据并正确解析它。

结论

AngularHttpClient模块提供了一个简单而强大的 API,用于在 Angular 应用程序中发出 HTTP 请求。有了我们在本文中讨论的信息,您现在应该能够HttpClient自信地使用该模块并遵循最佳实践来使您的应用程序更具可扩展性和可维护性。

原文链接:https://juejin.cn/post/7248267086635450423 作者:happyEnding

(0)
上一篇 2023年6月25日 上午10:00
下一篇 2023年6月25日 上午10:10

相关推荐

发表回复

登录后才能评论