Paldom / angular2-rest

Angular2 HTTP client to consume RESTful services. Built with TypeScript.
MIT License
248 stars 72 forks source link

enhancement: async requestInterceptor #6

Open Discountrobot opened 8 years ago

Discountrobot commented 8 years ago

The following code snippet will introduce a race condition, should one try to call SomeRESTClient before the _session has been populated, by the createSession request.

@Injectable()
@BaseUrl('https://api.someplace.com')
@DefaultHeaders({
  'Accept': 'application/json',
  'Content-Type': 'application/json'
})
export class SomeRESTClient extends RESTClient {

  private _session: any

  constructor(private _http: Http) {
    super(_http)
    this.setup()
  }

  protected requestInterceptor(req: Request) {
    if (this._session) {
      req.headers.append('Token', this._session.token)
    }
  }

  @POST('/sessions')
  @Produces(MediaType.JSON)
  private createSession( @Body data ): Observable<any> { return null }

  private setup () {
    let api_key = 'xxxx'
    this.createSession({ api_key }).subscribe(session => this._session = session)
  }
}

We should add the possibility to have the requestInterceptor return a promise or similar.

Paldom commented 8 years ago

Could you please give a small example (or simply extend the one above), how would you use the promise if requestInterceptor has support for that?

zhakhalov commented 8 years ago

Hello +1 to feature

Async interceptor could be important for OAuth process, which can has temporary token, needed to update before sending request

Could you also pass Response to responseInterceptor instead of Observable

Here is small example of async interceptor.


@Injectable()
@BaseUrl('https://api.someplace.com')
@DefaultHeaders({
  'Accept': 'application/json',
  'Content-Type': 'application/json'
})
export class SomeRESTClient extends RESTClient {

  constructor(
    @Inject(Http) http: Http
    @Inject(AuthService) private auth: AuthService
  ) {
    super(http)
    this.setup()
  }

  protected requestInterceptor(req: Request): Promise<void> {
    return this.auth
      .token(token => {
        req.headers.append('Autorization', `Bearer ${token}`)
      })
  }

  protected responseInterceptor(res: Response): Promise<void> {
    // do some stuff with raw response
  }
}