Разница между HttpModule и HttpClientModule


229

Какой из них использовать для создания фиктивного веб-сервиса для тестирования приложения Angular 4?



1
Вчера я написал о некоторых новых функциях в своем блоге: blog.jonrshar.pe/2017/Jul/15/angular-http-client.html
jonrsharpe


6
В учебнике используется HttpModule, а angular.io/guide/http использует HttpClientModule и не объясняет, когда следует использовать тот или иной вариант или какая версия Angular необходима для чего.
Микки Сигал

Посмотрите на этот пример Angular 8 HttpClient, чтобы использовать RESTFul API freakyjolly.com/…
Code Spy

Ответы:


338

Используйте HttpClientкласс из, HttpClientModuleесли вы используете Angular 4.3.x и выше:

import { HttpClientModule } from '@angular/common/http';

@NgModule({
 imports: [
   BrowserModule,
   HttpClientModule
 ],
 ...

 class MyService() {
    constructor(http: HttpClient) {...}

Это обновленная версия httpот @angular/httpмодуля со следующими улучшениями:

  • Перехватчики позволяют вставлять логику промежуточного программного обеспечения в конвейер
  • Неизменяемые объекты запроса / ответа
  • События прогресса для загрузки запроса и загрузки ответа

Вы можете прочитать о том, как это работает, в руководстве Insider по перехватчикам и механике HttpClient в Angular .

  • Типизированный синхронный доступ к телу ответа, включая поддержку типов тела JSON
  • JSON является предполагаемым значением по умолчанию и больше не требует явного анализа
  • Проверка после запроса и флеш-тестирование

В дальнейшем старый http-клиент будет устаревшим. Вот ссылки на сообщение о коммите и официальные документы .

Также обратите внимание, что старый http был введен с использованием Httpтокена класса вместо нового HttpClient:

import { HttpModule } from '@angular/http';

@NgModule({
 imports: [
   BrowserModule,
   HttpModule
 ],
 ...

 class MyService() {
    constructor(http: Http) {...}

Кроме того, новое, HttpClientкажется, требует tslibво время выполнения, поэтому вы должны установить его npm i tslibи обновить, system.config.jsесли вы используете SystemJS:

map: {
     ...
    'tslib': 'npm:tslib/tslib.js',

И вам нужно добавить еще одно сопоставление, если вы используете SystemJS:

'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',

1
Я пытаюсь импортировать HttpClientModule. Но «@ angular / common / http» отсутствует в каталоге node_modules, который я установил с помощью команды «npm start». Вы можете помочь?
Дирадж Кумар

1
@DheerajKumar, какую версию вы используете? доступно только в 4.3.0 и выше
Макс Корецкий,

Я скачал угловой быстрый старт из мерзавца. и в package.json "@ angular / common": "^ 4.3.0" присутствует. но нет @ angular / common / http.
Дирадж Кумар

удалить node_modulesпапку и запустить npm installснова
Макс Корецкий

5
Я столкнулся с той же самой проблемой (я использую System.js). В этом ответе отсутствует одна вещь: вам также нужно отобразить новый модуль в system.js следующим образом: '@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
Tyler O

43

Не хочу повторяться, а просто подвести итог другим способом (функции, добавленные в новый HttpClient):

  • Автоматическое преобразование из JSON в объект
  • Определение типа ответа
  • Событие стрельбы
  • Упрощенный синтаксис для заголовков
  • Перехватчики

Я написал статью, в которой рассказал о разнице между старым «http» и новым «HttpClient». Цель состояла в том, чтобы объяснить это как можно проще.

Просто о новом HttpClient в Angular


18

Это хорошая справка, она помогла мне переключить мои запросы http на httpClient

https://blog.hackages.io/angular-http-httpclient-same-but-different-86a50bbcc450

Он сравнивает их с точки зрения различий и дает примеры кода.

Это всего лишь несколько различий, с которыми я столкнулся при изменении служб на httpclient в моем проекте (заимствуя из упомянутой мной статьи):

Импорт

import {HttpModule} from '@angular/http';
import {HttpClientModule} from '@angular/common/http';

Запрос и анализ ответа:

@ Угловое / HTTP

 this.http.get(url)
      // Extract the data in HTTP Response (parsing)
      .map((response: Response) => response.json() as GithubUser)
      .subscribe((data: GithubUser) => {
        // Display the result
        console.log('TJ user data', data);
      });

@ Угловое / общие / HTTP

 this.http.get(url)
      .subscribe((data: GithubUser) => {
        // Data extraction from the HTTP response is already done
        // Display the result
        console.log('TJ user data', data);
      });

Примечание: вам больше не нужно извлекать возвращаемые данные явно; по умолчанию, если возвращаемые данные относятся к типу JSON, вам не нужно делать ничего лишнего.

Но если вам нужно проанализировать любой другой тип ответа, например, текст или блоб, убедитесь, что вы добавили responseTypeв запрос. Вот так:

Выполнение GET HTTP-запроса с responseTypeопцией:

 this.http.get(url, {responseType: 'blob'})
      .subscribe((data) => {
        // Data extraction from the HTTP response is already done
        // Display the result
        console.log('TJ user data', data);
      });

Добавление перехватчика

Я также использовал перехватчики для добавления токена для моей авторизации к каждому запросу:

Это хорошая ссылка: https://offering.solutions/blog/articles/2017/07/19/angular-2-new-http-interface-with-interceptors/

вот так:

@Injectable()
export class MyFirstInterceptor implements HttpInterceptor {

    constructor(private currentUserService: CurrentUserService) { }

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

        // get the token from a service
        const token: string = this.currentUserService.token;

        // add it if we have one
        if (token) {
            req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) });
        }

        // if this is a login-request the header is 
        // already set to x/www/formurl/encoded. 
        // so if we already have a content-type, do not 
        // set it, but if we don't have one, set it to 
        // default --> json
        if (!req.headers.has('Content-Type')) {
            req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
        }

        // setting the accept header
        req = req.clone({ headers: req.headers.set('Accept', 'application/json') });
        return next.handle(req);
    }
}

Это довольно хорошее обновление!


Вы должны включить соответствующую информацию в свой ответ, а не просто как ссылку
Майкл

1

Есть библиотека, которая позволяет вам использовать HttpClient со строго типизированными обратными вызовами .

Данные и ошибка доступны непосредственно через эти обратные вызовы.

Причина существования

Когда вы используете HttpClient с Observable, вы должны использовать .subscribe (x => ...) в остальной части вашего кода.

Это потому, что Observable HttpResponse<<T >> привязан к HttpResponse .

Это плотно пара в http с остальным кодом .

Эта библиотека инкапсулирует .subscribe (x => ...) и предоставляет только данные и ошибки через ваши Модели.

При использовании строго типизированных обратных вызовов вам нужно иметь дело только с вашими моделями в остальной части кода.

Библиотека называется angular-extended-http-client .

библиотека angular-extended-http-client на GitHub

библиотека angular-extended-http-client в NPM

Очень прост в использовании.

Пример использования

Сильно типизированные обратные вызовы

Успех:

  • IObservable < T>
  • IObservableHttpResponse
  • IObservableHttpCustomResponse < T>

Неудача:

  • IObservableError < TError>
  • IObservableHttpError
  • IObservableHttpCustomError < TError>

Добавить пакет в свой проект и в свой модуль приложения

import { HttpClientExtModule } from 'angular-extended-http-client';

и в импорте @NgModule

  imports: [
    .
    .
    .
    HttpClientExtModule
  ],

Ваши модели

//Normal response returned by the API.
export class RacingResponse {
    result: RacingItem[];
}

//Custom exception thrown by the API.
export class APIException {
    className: string;
}

Ваш Сервис

В вашей службе вы просто создаете параметры с этими типами обратного вызова.

Затем передайте их в метод get HttpClientExt .

import { Injectable, Inject } from '@angular/core'
import { RacingResponse, APIException } from '../models/models'
import { HttpClientExt, IObservable, IObservableError, ResponseType, ErrorType } from 'angular-extended-http-client';
.
.

@Injectable()
export class RacingService {

    //Inject HttpClientExt component.
    constructor(private client: HttpClientExt, @Inject(APP_CONFIG) private config: AppConfig) {

    }

    //Declare params of type IObservable<T> and IObservableError<TError>.
    //These are the success and failure callbacks.
    //The success callback will return the response objects returned by the underlying HttpClient call.
    //The failure callback will return the error objects returned by the underlying HttpClient call.
    getRaceInfo(success: IObservable<RacingResponse>, failure?: IObservableError<APIException>) {
        let url = this.config.apiEndpoint;

        this.client.get(url, ResponseType.IObservable, success, ErrorType.IObservableError, failure);
    }
}

Ваш Компонент

В вашем Компоненте ваш Сервис внедряется, а API getRaceInfo вызывается, как показано ниже.

  ngOnInit() {    
    this.service.getRaceInfo(response => this.result = response.result,
                                error => this.errorMsg = error.className);

  }

И, ответ и ошибка возвращается в обратные вызовы являются строго типизированными. Например. ответ имеет тип RacingResponse, а ошибка - APIException .

Вы имеете дело только со своими моделями в этих строго типизированных обратных вызовах.

Следовательно, остальная часть вашего кода знает только о ваших моделях.

Кроме того, вы все еще можете использовать традиционный маршрут и вернуть Observable < HttpResponse<T >> из Service API.


0

HttpClient - это новый API, поставляемый с 4.3, он обновил API с поддержкой событий прогресса, десериализацией json по умолчанию, перехватчиками и многими другими замечательными функциями. Подробнее здесь https://angular.io/guide/http

Http является более старым API и в конечном итоге будет устаревшим.

Поскольку их использование для базовых задач очень похоже, я бы посоветовал использовать HttpClient, поскольку это более современная и простая в использовании альтернатива.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.