1

Ich habe einen Service für die Bearbeitung aller HTTP-Anfragen erstellt. Es funktioniert perfekt. Aber ich möchte wissen, ob es einen Fehler in meiner Herangehensweise gibt und auch andere gute Ansätze wie beobachtbar wissen wollen?Der beste Ansatz zum Erstellen eines http-Anfragedienstes?

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); 
    } 

} 

Ich nenne dieses "post" -Methode den folgenden Code verwenden. Hier möchte ich , um ein Versprechen zu setzen, sobald die Anfrage abgeschlossen, ich möchte einige Nachricht anzeigen.

this.requestService.post({ 
    option: { 
    url: '', 
    cxfgroup: 'auth', 
     endpoint: 'getcustomerkeys', 
     data: { 
     userid: '[email protected]' 
     } 
    }, 
    log: 'login initiated!', 
    error: 'customerKeyError' 
}); 
+1

Werfen Sie einen Blick auf diese [** Antwort **] (https zu injizieren://stackoverflow.com/questions/43305876/set-global-data-to-property-from-get-request-before-continue/43307401#43307401) – Aravind

Antwort

1

Leider Libu, es ist alles mehr "einfach" als Code. Sie benötigen keine Klasse, Klasse und Klasse. Darüber hinaus ist es immer der beste Ansatz, ein Observable zurückzugeben. Tatsächlich gibt es keinen Vorteil, Versprechen statt beobachtbar zu verwenden. Wenn Sie eine beobachtbare zurückgeben können Sie "Kette" (mit switchMap), "Gruppe" (mit Gabel), etc

@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 
    } 
} 
+0

Danke für die Antwort. Entschuldigung, aber ich habe verschiedene Methoden wie die Post, bekomme etc .. Also muss ich diesen Code irgendwie trennen. –

+0

@Libu Mathew, in Ihrem Code kann ich nicht die verschiedenen Methoden sehen :( – Eliseo

+0

Ja. Aber ich brauche alle diese Fälle. Deshalb habe ich Code getrennt. –

1

HTTP-Service

Hier ist ein beobachtbares basierten Ansatz verwenden wir in unsere Projekte:

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; 
    } 
    } 
} 

Anwendungsbeispiel in Dienste

die sehr sim ist ple in Ihrem Dienst zu nutzen, so sieht es wird wie folgt aus:

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) 
    }); 
} 

Bitte beachten Sie, dass body, headers und query sind optional.

Anwendungsbeispiel in Komponenten

Und schließlich müssen Sie eine beobachtbare in Ihren Komponenten abonnieren, die Anforderung zu machen:

this.yourServiceName.makeRequest().subscribe(
    success => { 
    // handle success 
    }, 
    error => { 
    // handle error 
    } 
); 

Fehlerbehandlung

Fehler behandeln wir können Verwenden Sie HttpInterceptor so wird es in etwa so aussehen:

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 wird einige Middleware-Funktionalität auf alle HTTP-Anrufe mit HttpClient-Provider angewendet. Bitte beachten Sie, dass es nicht mit Http Provider funktioniert, da es in den neuesten Versionen veraltet ist. Und nicht zu vergessen die Abfangjäger in @NgModule enthalten:

@NgModule({ 
    providers: [ErrorHttpInterceptor] 
}) 

Ein ähnlicher Ansatz verwendet werden kann Authorization Token usw.

Verwandte Themen