Quale utilizzare per creare un finto servizio Web per testare l'app Angular 4?
Quale utilizzare per creare un finto servizio Web per testare l'app Angular 4?
Risposte:
Utilizzare la HttpClient
classe HttpClientModule
se si utilizza Angular 4.3.x e versioni successive:
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
HttpClientModule
],
...
class MyService() {
constructor(http: HttpClient) {...}
È una versione aggiornata di http
dal @angular/http
modulo con i seguenti miglioramenti:
- Gli intercettori consentono di inserire la logica del middleware nella pipeline
- Oggetti richiesta / risposta immutabili
- Eventi di avanzamento sia per il caricamento della richiesta che per il download della risposta
Puoi leggere come funziona nella guida di Insider sugli intercettori e la meccanica di HttpClient in angolare .
- Accesso al corpo della risposta tipizzato e sincrono, incluso il supporto per i tipi di corpo JSON
- JSON è un valore predefinito presunto e non deve più essere analizzato esplicitamente
- Verifica post-richiesta e framework di test basati su flush
Andando avanti il vecchio client http sarà deprecato. Ecco i collegamenti al messaggio di commit e ai documenti ufficiali .
Fai anche attenzione che il vecchio http sia stato iniettato usando il Http
token di classe invece del nuovo HttpClient
:
import { HttpModule } from '@angular/http';
@NgModule({
imports: [
BrowserModule,
HttpModule
],
...
class MyService() {
constructor(http: Http) {...}
Inoltre, in runtime HttpClient
sembrano essere necessari nuovi tslib
, quindi è necessario installarlo npm i tslib
e aggiornarlo system.config.js
se si utilizza SystemJS
:
map: {
...
'tslib': 'npm:tslib/tslib.js',
E devi aggiungere un'altra mappatura se usi SystemJS:
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
node_modules
cartella ed esegui di npm install
nuovo
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
Non voglio essere ripetitivo, ma semplicemente riassumere in altro modo (funzionalità aggiunte nel nuovo HttpClient):
Ho scritto un articolo, in cui ho coperto la differenza tra il vecchio "http" e il nuovo "HttpClient". L'obiettivo era spiegarlo nel modo più semplice possibile.
Questo è un buon riferimento, mi ha aiutato a cambiare le mie richieste http in httpClient
https://blog.hackages.io/angular-http-httpclient-same-but-different-86a50bbcc450
Confronta i due in termini di differenze e fornisce esempi di codice.
Queste sono solo alcune delle differenze che ho affrontato durante la modifica dei servizi in httpclient nel mio progetto (prendendo in prestito dall'articolo che ho citato):
import {HttpModule} from '@angular/http';
import {HttpClientModule} from '@angular/common/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);
});
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);
});
Nota: non è più necessario estrarre esplicitamente i dati restituiti; per impostazione predefinita, se i dati che ricevi sono di tipo JSON, non devi fare altro.
Tuttavia, se è necessario analizzare qualsiasi altro tipo di risposta come testo o BLOB, assicurarsi di aggiungere il responseType
nella richiesta. Così:
responseType
opzione: 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);
});
Ho anche usato gli intercettori per aggiungere il token per la mia autorizzazione ad ogni richiesta:
Questo è un buon riferimento: https://offering.solutions/blog/articles/2017/07/19/angular-2-new-http-interface-with-interceptors/
così:
@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);
}
}
È un aggiornamento piuttosto bello!
Esiste una libreria che consente di utilizzare HttpClient con callback fortemente tipizzati .
I dati e l'errore sono disponibili direttamente tramite questi callback.
Quando usi HttpClient con Observable, devi usare .subscribe (x => ...) nel resto del codice.
Ciò è dovuto al fatto osservabile < HttpResponse
< T
>> è legata alla HttpResponse .
Questo accoppia strettamente il livello http con il resto del codice .
Questa libreria incapsula la parte .subscribe (x => ...) ed espone solo i dati e l'errore attraverso i tuoi Modelli.
Con callback fortemente tipizzati, devi gestire i tuoi modelli solo nel resto del codice.
La libreria si chiama angular-extended-http-client .
libreria angular-extended-http-client su GitHub
libreria angular-extended-http-client su NPM
Molto facile da usare
I callback fortemente tipizzati sono
Successo:
T
>T
>Fallimento:
TError
>TError
>import { HttpClientExtModule } from 'angular-extended-http-client';
e nelle importazioni @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;
}
Nel tuo servizio, devi solo creare parametri con questi tipi di callback.
Quindi, passali al metodo get di 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);
}
}
Nel componente, viene iniettato il servizio e l' API getRaceInfo viene chiamata come mostrato di seguito.
ngOnInit() {
this.service.getRaceInfo(response => this.result = response.result,
error => this.errorMsg = error.className);
}
Sia la risposta che l' errore restituiti nei callback sono fortemente tipizzati. Per esempio. la risposta è di tipo RacingResponse e l' errore è APIException .
Gestisci i tuoi modelli solo in questi callback fortemente tipizzati.
Quindi, il resto del codice conosce solo i tuoi modelli.
Inoltre, è ancora possibile utilizzare il percorso tradizionale e restituire Observable < HttpResponse<
T >
> dall'API di servizio.
HttpClient è una nuova API fornita con 4.3, ha aggiornato le API con supporto per eventi di avanzamento, deserializzazione json per impostazione predefinita, intercettori e molte altre fantastiche funzionalità. Scopri di più qui https://angular.io/guide/http
Http è l'API precedente e alla fine sarà deprecata.
Poiché il loro utilizzo è molto simile per le attività di base, consiglierei di utilizzare HttpClient poiché è l'alternativa più moderna e facile da usare.