为不同的服务

时间:2017-09-22 00:17:06

标签: angular

我有一个非常实用的问题,可能有一些奇特的Angular Dependency Injection解决方案。

基本上:

我有拦截器A 来提供与服务A 进行通信的身份验证标头。

我有拦截器B 来提供与服务B 进行通信的Auth标头。

如何让服务A 的每个实例都具有拦截器A 的拦截器链?我如何保证服务B的反面?

这两个服务在整个应用程序中全局使用,因此我不能认为我只能在使用服务B / A的模块中定义新的HTTP_INTERCEPTOR注入令牌。

谢谢!

2 个答案:

答案 0 :(得分:2)

考虑到两个服务都在根注入器上注册,唯一的方法是创建一个类似于HttpClientModule但具有新DI令牌的新模块 - _T = someOtherClass而不是{{1 }和HttpClientB代替HttpClient。这将要求从HTTP_INTERCEPTORS_B中提取几个内部因素,因为它们不会被导出,例如HTTP_INTERCEPTORS

这样,服务B可以在common/http/src中拥有自己的注入器,并将HTTP客户端注入interceptingHandler

更简单的方法是让拦截器能够根据输入在实现之间切换。如图here所示,在请求期间与拦截器交互的唯一方法是通过请求参数或标头传递数据。

因此,服务A可以执行以下请求:

HTTP_INTERCEPTORS

拦截器接收标头并根据它做出决定:

HttpClientB

如果拦截器A和B仅特定于服务A和B而不是特定于应用程序的其余部分,则根本不应使用拦截器。相反,这应该直接在服务A和B中完成。

答案 1 :(得分:0)

以防万一将来有这个问题,这就是我最终要做的事情。

我需要将STATIC标头添加到HttpRequest,但可以轻松修改此解决方案以允许更多动态标头。

我使用以下内容创建了一个Attribute Add Interceptor:

<强> attribute.interceptor.ts

@Injectable()
export class AttributesInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const attributes = environment.attributes;
    let attributeReq = req;
    for (let i = 0; i !== attributes.length; i++) {
      const attribute = attributes[i];
      if (this.urlMatches(attribute.urls, req)) {
        // The url matches so let's apply the attribute
        attributeReq = attributeReq.clone({ headers: req.headers.set(attribute.header, attribute.value) });
      }
    }

    return next.handle(attributeReq);
  }

  urlMatches(urls: string[], req: HttpRequest<any>): boolean {
    for (let i = 0; i !== urls.length; i++) {
      if (req.url.includes(urls[i])) {
        return true;
      }
    }

    return false;
  }
}

并在环境文件中定义了我的静态属性:

<强> environment.local.ts

export const endpoints = {
  midway: 'http://localhost:8080',
  builds: 'http://localhost:7245'
};

export const environment = {
  production: false,
  logLevel: LogSeverity.INFO,
  endpoints: endpoints,
  attributes: <Attribute[]> [
    {
      header: 'X-COMPANY',
      value: 'SECRET-TOKEN',
      urls: [ endpoints.midway ]
    }
  ]
};

将属性定义为:

export class Attribute {
  header: string;
  value: string;
  urls: string[];
}

所以现在我可以为任何服务调用添加特定的静态标头,只需将此属性数组附加到服务基础URL和标头/值。

这个解决方案可以扩展到更复杂的用例,但这个简单的解决方案完全符合我的需要!