我创建了一个用于处理所有http请求的服务。它工作得很好。但我想知道我的方法是否有任何错误,并且还想知道其他好的方法,如可观察的?
request.service.js
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { MessageService } from './message.service';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' })
};
interface IRequestOption {
url: string;
cxfgroup: string;
endpoint: string;
data: object;
}
interface IRequestBody {
option: IRequestOption;
log: string;
error: string;
}
class HTTP {
private messageService: MessageService;
constructor(http, messageService, url: string, body: object, log: string, error: string) {
this.callHTTP(http, url, body, log, error);
this.messageService = messageService;
}
callHTTP(http, url, body, log, error) {
return http.post(url, body, httpOptions).toPromise()
.then(this.extractData)
.catch(this.handleErrorPromise);
}
private extractData(res: Response) {
// let body = res.json();
// return body['data'] || {};
return res || {};
}
private handleErrorPromise(error: Response | any) {
console.error(error.message || error);
return Promise.reject(error.message || error);
}
}
class RequestFactory {
private baseURL = 'https://app.domain.com/cxf/';
/**
* CXF ENPOINTS
*/
private endpoints: any = {
"auth": {
"getcustomerkeys": "auth/getcustomerkeys"
}
};
call(http, messageService, options: IRequestOption, log: string, error: string) {
let url: string = options.url ? options.url : this.baseURL;
if (this.endpoints.hasOwnProperty(options['cxfgroup'])) {
url += this.endpoints[options.cxfgroup][options.endpoint];
}
return new HTTP(http, messageService, url, options.data, log, error);
}
}
@Injectable()
export class RequestService {
constructor(private http: HttpClient, private messageService: MessageService) { }
post(request: IRequestBody) {
let requestFactory = new RequestFactory();
requestFactory.call(this.http, this.messageService, request.option, request.log, request.error);
}
}
我正在使用以下代码调用此“post”方法。我想要的 一旦请求完成我想要显示一些设置承诺 消息。
this.requestService.post({
option: {
url: '',
cxfgroup: 'auth',
endpoint: 'getcustomerkeys',
data: {
userid: 'user@domain.com'
}
},
log: 'login initiated!',
error: 'customerKeyError'
});
答案 0 :(得分:2)
HTTP服务
以下是我们在项目中使用的基于观察的方法:
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class HttpService {
constructor(private http: HttpClient) {}
/**
* Invoke function should be able to handle any HTTP request based on the @params
*/
invoke(params): Observable<any> {
if (params) {
const method = params.method.toLowerCase();
const { url, path, body, headers, query } = params;
const requestURL = `${url}/${path}`;
let request;
let requestParams = new HttpParams();
let requestHeaders = new HttpHeaders();
/**
* DEFAULT HEADERS
*/
requestHeaders = requestHeaders.set('Content-Type', 'application/json');
/**
* CUSTOM HEADERS
*/
if (headers) {
for (const key in headers) {
if (headers.hasOwnProperty(key)) {
requestHeaders = requestHeaders.append(key, headers[key]);
}
}
}
/**
* CUSTOM REQUEST QUERY (?key=value)
*/
if (query) {
for (const key in query) {
if (query.hasOwnProperty(key)) {
requestParams = requestParams.append(key, query[key]);
}
}
}
const requestOptions = {
headers: requestHeaders,
params: requestParams,
};
/**
* HANDLE GET, POST etc. REQUESTS
*/
if (method === 'get') {
request = this.http[method](requestURL, requestOptions);
} else if (method === 'post' || method === 'put') {
request = this.http[method](
requestURL,
JSON.stringify(body),
requestOptions,
);
} else if (method === 'delete') {
request = this.http.request(method, requestURL, {
...requestOptions,
body: JSON.stringify(body),
});
} else {
console.error('Unknown request method.');
}
/**
* RETURN API REQUEST
*/
return request;
}
}
}
服务中的使用示例
在您的服务中使用它非常简单,所以它看起来像这样:
constructor(private http: HttpService) {}
makeRequest() {
return this.http.invoke({
method: 'POST', // method like POST, GET etc.
url: 'http://blabla', // base URL
path: 'makeReq', // API endpoint
body: ..., // body for POST or PUT requests
headers: {headerName: 'HeaderValue'} // headers you need to add to your request
query: {query: 'queryValue'} // URL query to be added (eg. ?query=queryValue)
});
}
请注意,body
,headers
和query
是可选的。
组件中的使用示例
最后,您需要订阅组件中的Observable来发出请求:
this.yourServiceName.makeRequest().subscribe(
success => {
// handle success
},
error => {
// handle error
}
);
为了处理错误,我们可以使用HttpInterceptor,所以它看起来像这样:
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse,
HTTP_INTERCEPTORS,
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { _throw } from 'rxjs/observable/throw';
import 'rxjs/add/operator/catch';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(
req: HttpRequest<any>,
next: HttpHandler,
): Observable<HttpEvent<any>> {
return next.handle(req).catch(errorReponse => {
let error: string;
if (errorReponse instanceof HttpErrorResponse) {
error = errorReponse.error;
const { status, statusText, message } = errorReponse;
const errMsg = `HTTP ERROR: ${status} - ${statusText}\n${message}\n\nBACKEND RESPONSE: `;
console.error(errMsg, error);
} else {
error = null;
}
return _throw(error);
});
}
}
export const ErrorHttpInterceptor = {
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptor,
multi: true,
};
HttpInterceptor
会将一些中间件功能应用于使用HttpClient
提供程序进行的所有HTTP调用。请注意,它不适用于Http
提供程序,因为它在最新版本中已弃用。并且不要忘记在@NgModule
中包含拦截器:
@NgModule({
providers: [ErrorHttpInterceptor]
})
可以使用类似的方法来注入Authorization
令牌等。
答案 1 :(得分:1)
对不起Libu,它更简单&#34;简单&#34;比你的代码。你不需要创建类,类和类。此外,最好的方法是它始终返回一个Observable。实际上,使用promise而不是observable是没有优势的。如果你返回一个观察者,你可以&#34;链&#34; (使用switchMap),&#34; group&#34; (使用fork)等
@Injectable()
export class RequestService {
private baseURL = 'https://app.domain.com/cxf/';
constructor(private http: HttpClient)
post(request: IRequestBody) {
let url: string = options.url ? options.url : this.baseURL;
if (this.endpoints.hasOwnProperty(options['cxfgroup'])) {
url += this.endpoints[options.cxfgroup][options.endpoint];
}
let requestFactory = new RequestFactory();
this.http.post(url,this.messageService, request.option)
.do(console.log(request.log)) //when the request sucesfully
//show in console
.catch(console.log(request.error)); //if fail, show in console the error
}
}