Qual usar para criar um serviço da web simulado para testar o aplicativo Angular 4?
Qual usar para criar um serviço da web simulado para testar o aplicativo Angular 4?
Respostas:
Use a HttpClient
classe from HttpClientModule
se você estiver usando o Angular 4.3.xe acima:
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
HttpClientModule
],
...
class MyService() {
constructor(http: HttpClient) {...}
É uma versão atualizada http
do @angular/http
módulo from , com as seguintes melhorias:
- Os interceptores permitem que a lógica do middleware seja inserida no pipeline
- Objetos imutáveis de solicitação / resposta
- Eventos de progresso para upload de solicitação e download de resposta
Você pode ler sobre como ele funciona no guia do Insider em interceptores e na mecânica HttpClient no Angular .
- Acesso de corpo de resposta síncrona digitado, incluindo suporte para tipos de corpo JSON
- JSON é um padrão assumido e não precisa mais ser analisado explicitamente
- Estrutura de teste baseada em verificação pós-solicitação e liberação
No futuro, o cliente http antigo será descontinuado. Aqui estão os links para a mensagem de confirmação e os documentos oficiais .
Observe também que o http antigo foi injetado usando o Http
token de classe em vez do novo HttpClient
:
import { HttpModule } from '@angular/http';
@NgModule({
imports: [
BrowserModule,
HttpModule
],
...
class MyService() {
constructor(http: Http) {...}
Além disso, novas HttpClient
parecem exigir tslib
em tempo de execução, portanto, você deve instalá-lo npm i tslib
e atualizar system.config.js
se estiver usando SystemJS
:
map: {
...
'tslib': 'npm:tslib/tslib.js',
E você precisa adicionar outro mapeamento se usar o SystemJS:
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
node_modules
pasta e execute npm install
novamente
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
Não queira ser repetitivo, mas apenas resumir de outra maneira (recursos adicionados no novo HttpClient):
Escrevi um artigo, onde abordava a diferença entre o antigo "http" e o novo "HttpClient". O objetivo era explicá-lo da maneira mais fácil possível.
Esta é uma boa referência, pois me ajudou a mudar minhas solicitações http para httpClient
https://blog.hackages.io/angular-http-httpclient-same-but-different-86a50bbcc450
Ele compara os dois em termos de diferenças e fornece exemplos de código.
Estas são apenas algumas diferenças que eu lidei ao mudar os serviços para httpclient no meu projeto (tomando emprestado o artigo que mencionei):
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: Você não precisa mais extrair os dados retornados explicitamente; por padrão, se os dados retornados forem do tipo JSON, não será necessário fazer nada extra.
Mas, se você precisar analisar qualquer outro tipo de resposta, como texto ou blob, adicione-o responseType
na solicitação. Igual a:
responseType
opção: 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);
});
Também usei interceptores para adicionar o token para minha autorização a cada solicitação:
Esta é uma boa referência: https://offering.solutions/blog/articles/2017/07/19/angular-2-new-http-interface-with-interceptors/
igual a:
@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);
}
}
É uma atualização bastante agradável!
Existe uma biblioteca que permite que você use HttpClient com retornos de chamada fortemente tipados .
Os dados e o erro estão disponíveis diretamente através desses retornos de chamada.
Ao usar o HttpClient com o Observable, você deve usar .subscribe (x => ...) no restante do seu código.
Isso ocorre porque o Observable HttpResponse
<< T
>> está vinculado ao HttpResponse .
Isso une firmemente a camada http com o restante do seu código .
Esta biblioteca encapsula a parte .subscribe (x => ...) e expõe apenas os dados e erros nos seus modelos.
Com retornos de chamada fortemente digitados, você só precisa lidar com seus modelos no restante do seu código.
A biblioteca é chamada angular-extended-http-client .
biblioteca angular-extended-http-client no GitHub
biblioteca angular-extended-http-client no NPM
Muito fácil de usar.
Os retornos de chamada fortemente digitados são
Sucesso:
T
>T
>Falha:
TError
>TError
>import { HttpClientExtModule } from 'angular-extended-http-client';
e nas importações @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;
}
No seu serviço, você acabou de criar parâmetros com esses tipos de retorno de chamada.
Em seguida, passe-os para o método get do 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);
}
}
No seu componente, seu serviço é injetado e a API getRaceInfo é chamada conforme mostrado abaixo.
ngOnInit() {
this.service.getRaceInfo(response => this.result = response.result,
error => this.errorMsg = error.className);
}
Tanto a resposta quanto o erro retornado nos retornos de chamada são fortemente digitados. Por exemplo. resposta é do tipo RacingResponse e erro é APIException .
Você lida apenas com seus modelos nesses retornos de chamada fortemente tipados.
Portanto, o restante do seu código conhece apenas seus modelos.
Além disso, você ainda pode usar a rota tradicional e retornar Observable < HttpResponse<
T >
> da API de serviço.
O HttpClient é uma nova API que veio com a 4.3, que atualizou as APIs com suporte para eventos de progresso, desserialização de json por padrão, Interceptores e muitos outros ótimos recursos. Veja mais aqui https://angular.io/guide/http
Http é a API mais antiga e será descontinuada.
Como o uso deles é muito semelhante para tarefas básicas, eu recomendaria o uso do HttpClient, pois é a alternativa mais moderna e fácil de usar.