前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >gRPC-Web中的拦截器

gRPC-Web中的拦截器

作者头像
CNCF
发布2020-07-02 20:11:28
1.6K0
发布2020-07-02 20:11:28
举报
文章被收录于专栏:CNCF

我们很高兴地宣布从1.1.0版开始支持gRPC-web中的拦截器(interceptor)。虽然当前的设计基于其他gRPC语言提供的gRPC客户端拦截器,但它也包括gRPC特定于Web的特性,这些特性应该会使拦截器易于采用,并与现代Web框架一起使用。

介绍

与其他gRPC语言类似,gRPC-web支持unary和server-streaming拦截器。对于每种拦截器,我们都定义了一个包含单个intercept()方法的接口:

  • UnaryInterceptor
  • StreamInterceptor

UnaryInterceptor接口的声明方式如下:

代码语言:javascript
复制
/*
* @interface
*/
const UnaryInterceptor = function() {};


/**
 * @template REQUEST, RESPONSE
 * @param {!Request<REQUEST, RESPONSE>} request
 * @param {function(!Request<REQUEST,RESPONSE>):!Promise<!UnaryResponse<RESPONSE>>}
 *     invoker
 * @return {!Promise<!UnaryResponse<RESPONSE>>}
 */
UnaryInterceptor.prototype.intercept = function(request, invoker) {};

intercept()方法接受两个参数:

  • 类型为gRPC.web.Request的request。
  • invoker,它在被调用时执行实际的RPC。

StreamInterceptor接口声明类似,只是调用器返回类型是ClientReadablaStream而不是Promise。有关实现的详细信息,请参阅interceptor.js。

https://github.com/grpc/grpc-web/blob/master/javascript/net/grpc/web/interceptor.js

注:StreamInteceptor可以应用于任何具有ClientReadableStream返回类型的RPC,无论它是unary还是server-streaming RPC。

我能用拦截器做什么?

拦截器允许你执行以下操作:

  • 在传递原始gRPC请求之前更新它-例如,你可能会注入额外的信息,如auth标头。
  • 操作原始调用程序函数的行为,例如绕过调用,以便你可以改用缓存结果。
  • 在响应返回到客户端之前更新响应。

接下来你将看到一些示例。

Unary拦截器示例

下面给出的代码说明了执行以下操作的unary拦截器:

  • 它在RPC之前为gRPC请求消息添加一个字符串。
  • 收到gRPC响应消息后,它会在消息前面加上一个字符串。

这个简单的一元拦截器被定义为实现UnaryInterceptor接口的类:

代码语言:javascript
复制
/**
 * @constructor
 * @implements {UnaryInterceptor}
 */
const SimpleUnaryInterceptor = function() {};


/** @override */
SimpleUnaryInterceptor.prototype.intercept = function(request, invoker) {
  // Update the request message before the RPC.
  const reqMsg = request.getRequestMessage();
  reqMsg.setMessage('[Intercept request]' + reqMsg.getMessage());


  // After the RPC returns successfully, update the response.
  return invoker(request).then((response) => {
    // You can also do something with response metadata here.
    console.log(response.getMetadata());


    // Update the response message.
    const responseMsg = response.getResponseMessage();
    responseMsg.setMessage('[Intercept response]' + responseMsg.getMessage());


    return response;
  });
};

Stream截取器示例 在使用StreamInterceptor拦截来自ClientReadableStream的服务器流响应时需要更加小心。以下是要遵循的主要步骤:

  1. 创建一个ClientReadableStream-wrapper类,并使用它拦截流事件,比如接收服务器响应。
  2. 创建一个实现StreamInterceptor并使用stream wrapper的类。

下面的示例stream-wrapper类截取响应,并在响应消息前面附加一个字符串:

代码语言:javascript
复制
/**
 * A ClientReadableStream wrapper.
 *
 * @template RESPONSE
 * @implements {ClientReadableStream}
 * @constructor
 * @param {!ClientReadableStream<RESPONSE>} stream
 */
const InterceptedStream = function(stream) {
  this.stream = stream;
};


/** @override */
InterceptedStream.prototype.on = function(eventType, callback) {
  if (eventType == 'data') {
    const newCallback = (response) => {
      // Update the response message.
      const msg = response.getMessage();
      response.setMessage('[Intercept response]' + msg);
      // Pass along the updated response.
      callback(response);
    };
    // Register the new callback.
    this.stream.on(eventType, newCallback);
  } else {
    // You can also override 'status', 'end', and 'error' eventTypes.
    this.stream.on(eventType, callback);
  }
  return this;
};


/** @override */
InterceptedStream.prototype.cancel = function() {
  this.stream.cancel();
  return this;
};

示例拦截器的intercept()方法返回一个wrapped stream:

代码语言:javascript
复制
/**
 * @constructor
 * @implements {StreamInterceptor}
 */
const TestStreamInterceptor = function() {};


/** @override */
TestStreamInterceptor.prototype.intercept = function(request, invoker) {
  return new InterceptedStream(invoker(request));
};

绑定拦截器

通过使用适当的Option键传递拦截器实例数组,可以在实例化客户端时将拦截器绑定到客户端:

代码语言:javascript
复制
const promiseClient = new MyServicePromiseClient(
    host, creds, {'unaryInterceptors': [interceptor1, interceptor2, interceptor3]});


const client = new MyServiceClient(
    host, creds, {'streamInterceptors': [interceptor1, interceptor2, interceptor3]});

注:拦截器的执行顺序与请求处理和响应处理的顺序相反,如下所示:

反馈

发现grpc-web有问题还是需要功能?通过grpc-web仓库提交问题。如果你有一般性的问题或意见,请考虑发布到gRPC邮件列表或向我们发送电子邮件至gRPC-web-team@google.com。

https://github.com/grpc/grpc-web/issues/new

https://groups.google.com/forum/#!forum/grpc-io

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CNCF 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档