上云无忧 > 文档中心 > 腾讯云 API 网关插件 - 自定义请求体
腾讯云 API 网关插件 - 自定义请求体

文档简介:
操作场景: 客户端发给业务后端的请求体中包含很多字段,如果您需要修改请求体内容,可以通过自定义请求体插件实现。
*此产品及展示信息均由腾讯云官方提供。免费试用 咨询热线:400-826-7010,为您提供专业的售前咨询,让您快速了解云产品,助您轻松上云! 微信咨询
  免费试用、价格特惠

操作场景

客户端发给业务后端的请求体中包含很多字段,如果您需要修改请求体内容,可以通过自定义请求体插件实现。
自定义请求体插件作用在请求过程中, 请求体改写服务可部署在云函数、公网、或内网 VPC 上。客户端请求 API 网关后,API 网关会将请求内容转发到请求体改写服务中,请求体内容修改完成后,将修改后的请求体响应给 API 网关,API 网关再将修改后的请求体转发给业务后端。

前提条件

对于部署在云函数的认证服务,需开通 云函数 服务。
说明:
自定义请求体插件目前仅支持事件函数,不支持 Web 函数。

操作步骤

步骤1:创建修改请求体函数

对于部署在公网或内网 VPC 的认证函数,可省略该步骤。
1. 登录 云函数控制台
2. 在左侧导航栏,单击函数服务,进入函数列表页面。
3. 单击页面左上角的新建,新建一个函数,内容为修改请求体。

步骤2:创建自定义请求体插件

1. 登录 API 网关控制台
2. 在左侧导航栏,单击插件 > 自定义插件,进入自定义插件列表页面。
3. 单击页面左上角的新建,新建一个自定义请求体插件。
对于部署在云函数的认证服务,创建自定义请求体插件时需要填写的数据如下:
参数
是否必填
说明
选择函数
必填
选择修改请求体的函数所在的命名空间、名称和版本。
后端超时
必填
设置 API 网关转发到修改请求体的函数的后端超时时间,超时时间的最大限制为30分钟。在 API 网关调用修改请求体的函数,未在超时时间内获得响应时,API 网关将终止此次调用,并返回相应的错误信息。
自定义内容
必填
设置 API 网关发送给修改请求体的函数的请求内容,支持选择 Header、Body、Query。未选择的请求内容部分将不被修改,直接转发给业务后端。
Base64 编码
必填
是否将请求内容 Base64 编码后再转发给修改请求体的函数,一般适用于请求内容是二进制的情况。
对于部署在公网的认证服务,创建自定义认证插件时需要填写的数据如下:
参数
是否必填
说明
请求方法
必填
请求自定义请求体函数的方法,支持 GET、POST、PUT、DELETE、HEAD、ANY。
公网服务
必填
请求体服务访问地址,支持 HTTP 和 HTTPS 协议。
路径匹配模式
必填
支持后端路径匹配和全路径匹配两种方式。
后端路径匹配:直接使用配置的路径请求服务。
全路径匹配:使用去除请求路径的路径请求服务,如 API 路径配置为 /a/,请求路径为 /a/b,开启全路径匹配后,传输给服务的为 /b。

对于部署在内网 VPC 的认证服务,创建自定义认证插件时需要填写的数据如下:
参数
是否必填
说明
选择 VPC
必填
选择自定义请求改写服务所属的 VPC。
请求方法
必填
请求自定义请求改写服务的方法,支持 GET、POST、PUT、DELETE、HEAD、ANY。
后端地址
必填
自定义请求体服务访问地址,支持 HTTP 和 HTTPS 协议。

步骤3:绑定 API

1. 在列表中选中 步骤2 创建好的插件,单击操作列的绑定 API
2. 在绑定 API 弹窗中选择服务和环境,并选择需要绑定插件的 API。

3. 单击确定,即可将插件绑定到 API,此时插件的配置已经对 API 生效。

自定义请求体云函数的编写方法

返回值定义

API 网关自定义请求体插件需要接受自定义请求体云函数返回特定格式的 Response,具体格式如下:
		
{
"replace_headers":{
"header1":"header1-value",
"header2":"header2-value"
},
"remove_headers":[
"header3",
"header4"
],
"replace_body":"hello",
"replace_querys":{
"query1":"query1-value",
"query2":"query2-value"
},
"remove_querys":[
"query3",
"query4"
]
}

Python Demo

使用 Python 语言修改请求体的函数的编写方法请您参见 自定义请求体 Python Demo

Java Demo

		
package com.example.demo;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.qcloud.services.scf.runtime.events.APIGatewayProxyRequestEvent;
public class Demo {
public String mainHandler(APIGatewayProxyRequestEvent request) {
System.out.println("helloworld");
System.out.println(request.getHttpMethod());
JsonObject resp = new JsonObject();
headerHandler(request, resp);
headerQuery(request, resp);
headerBody(request, resp);
return resp.toString();
}
private void headerHandler(APIGatewayProxyRequestEvent request, JsonObject resp) {
JsonObject replace_headers = new JsonObject();
JsonArray remove_headers = new JsonArray();
// 示例:替换或新增 header1 header2
replace_headers.addProperty("header1", "header1-value");
replace_headers.addProperty("header2", "header2-value");
// 示例:删除 header3
remove_headers.add("header3");
resp.add("replace_headers", replace_headers);
resp.add("remove_headers", remove_headers);
}
private void headerQuery(APIGatewayProxyRequestEvent request, JsonObject resp) {
JsonObject replace_querys = new JsonObject();
JsonArray remove_querys = new JsonArray();
// 示例:替换或新增 query1 query2
replace_querys.addProperty("query1", "query1-value");
replace_querys.addProperty("query2", "query2-value");
// 示例:删除 header3
remove_querys.add("query3");
resp.add("replace_querys", replace_querys);
resp.add("remove_querys", remove_querys);
}
private void headerBody(APIGatewayProxyRequestEvent request, JsonObject resp) {
resp.addProperty("replace_body", "{'name':'Yagr'}");
}
}

PluginData

		
{
"endpoint_timeout":15, // 后端超时时间,单位秒,合法值:0 ~ 60 秒
"func_name":"test_name", // 自定义函数名称
"func_namespace":"test_namespace", // 自定义函数命名空间
"func_qualifier":"$LATEST", // 自定义函数版本
"is_base64_encoded":true, // 是否将请求内容 Base64 编码后再转发给修改请求体的函数
"is_send_req_body":true, // 是否将请求的Body内容发送到函数
"is_send_req_headers":true, // 是否将请求的Header内容发送到函数
"is_send_req_querys":true, // // 是否将请求的Query内容发送到函数
"user_id":1253970226 // appid
}

注意事项

每次将自定义插件绑定到一个网关 API 时,相当于为修改请求体的函数创建了一个该网关 API 的触发器。在 SCF 侧删除触发器,相当于把插件和 API 解绑。

自定义服务类型规则

自定义插件的自定义服务类型,支持绑定不同实例上的服务 API,规则请参见 插件概述-已支持自定义插件类型

示例代码

自定义请求体时,HTTP 服务的示例代码如下:
Python 2.7
			
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
import json
PORT_NUMBER = 8022
def handle_header(header, response):
replace_headers = {} # 需要替换或者新增的header
remove_headers = [] # 需要删除的header
header_parameters = header # 客户端原始请求的header内容
if header_parameters is None or not isinstance(header_parameters, dict):
print("Invalid event.headerParameters")
return
# 示例:替换或新增 header1
replace_headers["header1"] = "header1"
# 示例:删除 header2
if header_parameters.get("header2") is not None:
remove_headers.append("header2")
# replace_headers 和 remove_headers 至少有一个非空
if len(replace_headers) < 1 and len(remove_headers) < 1:
print("Invalid custom request headers")
return
response["replace_headers"] = replace_headers
response["remove_headers"] = remove_headers
def handle_body(body, response):
replace_body = "" # 替换之后的body内容
# 示例:替换body
if body is not None:
replace_body = "hello world"
# replace_body 必须为字符串类型
if not isinstance(replace_body, str):
print("Invalid custom request body")
return
response["replace_body"] = replace_body
def handle_query(query, response):
replace_query = {} # 需要替换或者新增的query
remove_query = [] # 需要删除的query
query_parameters = query
if query_parameters is None or not isinstance(query_parameters, dict):
print("Invalid event.queryStringParameters")
return
# 示例:替换或新增 query1
replace_query["query1"] = "query1"
# 示例:删除原始请求中的 query2
if query_parameters.get("query2") is not None:
remove_query.append("query2")
# replace_query 和 remove_query 至少有一个非空
if len(replace_query) < 1 and len(remove_query) < 1:
print("Invalid custom request query")
return
response["replace_query"] = replace_query
response["remove_query"] = remove_query
class MyHandler(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
def do_POST(self):
response = {}
try:
request_body = self.rfile.read(int(self.headers.getheader("Content-length")))
except:
request_body = "no body."
# 重写header
handle_header(self.headers.__dict__, response)
# 重写query
parsed_url = urlparse(self.path)
request_query = parse_qs(parsed_url.query)
handle_query(request_query, response)
# 重写body
handle_body(request_body, response)
        self._set_headers()
self.wfile.write(json.dumps(response).encode('utf-8'))
return
try:
server = HTTPServer(('', PORT_NUMBER), MyHandler)
print(f'Started HTTP server on port {PORT_NUMBER}')
# Wait forever for incoming http requests
server.serve_forever()
except KeyboardInterrupt:
print('^C received, shutting down the web server')
server.socket.close()
相似文档
  • 操作场景: API 网关响应给客户端响应体中包含很多字段,如果您需要修改响应体内容,可以通过自定义响应体插件实现。
  • 操作场景: 防重放插件是 API 网关提供的针对重放攻击进行 API 保护的能力。您可以创建防重放插件并绑定到 API 生效,以保护您的后端服务。
  • 操作场景: 如果 API 网关提供的认证鉴权方式不能满足您的需求,您可以使用自定义认证插件,通过您自定义的代码进行认证鉴权。 自定义认证插件作用在请求过程中,客户端请求 API 网关后,API 网关会将请求内容转发到认证函数中。您可以将认证函数部署在云函数上,公网、或内网 VPC 上,认证通过后请求才会被转发给业务后端,否则将拒绝请求。
  • 操作场景: 通过配置缓存插件,API 网关可存储后端应答,当遇到相同请求参数的请求时,API 网关将直接返回缓存的应答,无需转发到后端服务,以此达到降低后端的负荷,减少时延,增加平滑度的目的。
  • 操作场景: 条件路由插件可根据参数取值转发到不同后端。根据请求的参数取值与系统参数取值,按规则将不同的客户端请求转发到不同后端地址,可广泛应用于灰度发布、蓝绿发布、租户路由等场景。
官方微信
联系客服
400-826-7010
7x24小时客服热线
分享
  • QQ好友
  • QQ空间
  • 微信
  • 微博
返回顶部