gpt4 book ai didi

azure-api-management - 将传入的 GET 请求转换为后端服务的 POST 请求的 APIM 策略

转载 作者:行者123 更新时间:2023-12-05 09:19:50 24 4
gpt4 key购买 nike

注意:在下面查看我自己的答案

几个小时以来,我一直在浏览这些精简的文档。我需要的是:

我有一个来自只能发送 GET 请求的系统的传入 GET 请求。我的后端服务需要 POST 请求。

关于我应该使用什么样的 APIM 政策或政策组合,有人能给我指出正确的方向吗?

我正在使用政策引用,但仍然无法想出一个像样的解决方案: https://msdn.microsoft.com/en-us/library/azure/dn894081.aspx

最佳答案

我找到了解决办法。

场景如下:我要求客户端调用 APIM 端点并且只返回简单的响应。即....认证=真/假。

我有一个来自只能发送 GET 请求的系统的传入 GET 请求。我的后端服务需要 POST 请求。

这是来自客户端的 GET 调用,它只能发送 GET 请求:https:///api/v1//10010810?pin=1212&property=Sydney&subscription-key=XXXXXXXXXXXXXX&debugging=1

这是我的政策:

<policies>
<inbound>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<trace source="defaultTrace">
@{
return System.String.Format("The passed in querystring paramters were | pin: {0} | debugging: {1} | property: {2} | subscription-key: {3}",
context.Request.Url.Query.GetValueOrDefault("pin"),
context.Request.Url.Query.GetValueOrDefault("debugging"),
context.Request.Url.Query.GetValueOrDefault("property"),
context.Request.Url.Query.GetValueOrDefault("subscription-key")
);
}
</trace>
<set-variable name="requestPin" value="@(context.Request.Url.Query.GetValueOrDefault("pin"))" />
<set-variable name="debugging" value="@(context.Request.Url.Query.GetValueOrDefault("debugging"))" />
<trace source="defaultTrace">
@{
return System.String.Format(
"Removing the following querystring parameters from url as we don't want to pass these ones to the backend service debugging: {0} | subscription-key: {1} | pin: {2}",
context.Request.Url.Query.GetValueOrDefault("debugging"),
context.Request.Url.Query.GetValueOrDefault("subscription-key"),
context.Request.Url.Query.GetValueOrDefault("pin")
);
}
</trace>
<set-query-parameter name="subscription-key" exists-action="delete" />
<set-query-parameter name="debugging" exists-action="delete" />
<set-query-parameter name="pin" exists-action="delete" />
<base />
</inbound>
<backend>
<!-- Setup a response-variable-name to hold the response from the backend service-->
<send-request mode="copy" response-variable-name="microservice-response" timeout="20" ignore-error="false">
<!-- Set the method to POST as the backend service MUST receive a POST call-->
<set-method>POST</set-method>
<set-body>
@{
// Get the pin from the url as we need it to construct the POST body
var requestPin = context.Variables.GetValueOrDefault<string>("requestPin");

var postBody = new JObject(
new JProperty("Type", "Pin"),
new JProperty("Value", requestPin)
).ToString();
return postBody;
}
</set-body>
</send-request>
</backend>
<outbound>
<choose>
<when condition="@(((IResponse)context.Variables["microservice-response"]).StatusCode == 200)">
<!-- When the micro-service returned a valid response we put the response into the previously created variable called microservice-response -->
<return-response>
<set-status code="200" reason="Ok" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]).Body.As<JObject>();

if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", true),
new JProperty("MicroserviceResponse", microserviceResponse),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", true)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</when>
<when condition="@(((IResponse)context.Variables["microservice-response"]).StatusCode == 401)">
<!-- When the micro-service returned a valid response we put the response into the previously created variable called microservice-response -->
<return-response>
<set-status code="401" reason="Error" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]);

if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", false),
new JProperty("MicroserviceResponse", microserviceResponse.Body.As<JObject>().ToString()),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</when>
<when condition="@(((IResponse)context.Variables["microservice-response"]).StatusCode == 400)">
<!-- When the micro-service returned a valid response we put the response into the previously created variable called microservice-response -->
<return-response>
<set-status code="200" reason="Ok" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]);

if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", false),
new JProperty("MicroserviceResponse", microserviceResponse.Body.As<JObject>().ToString()),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</when>
<otherwise>
<return-response>
<!-- When the micro-service threw an exception we just want to show the caller Authenticated = false -->
<!--<set-status code="500" reason="Error" />-->
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
var microserviceResponse = ((IResponse)context.Variables["microservice-response"]);

if(debuggingVariable == "1")
{
var returnResponse = new JObject(
new JProperty("Authenticated", false),
new JProperty("MicroserviceResponse", microserviceResponse.Body.As<JObject>().ToString()),
new JProperty("StatusCode", ((IResponse)context.Variables["microservice-response"]).StatusCode)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</otherwise>
</choose>
<base />
</outbound>
<on-error>
<!-- When APIM threw an exception -->
<trace source="defaultTrace">
@{
var returnResponse = new JObject
(
new JProperty("Authenticated", false),
new JProperty("Source", context.LastError.Source),
new JProperty("Reason", context.LastError.Reason),
new JProperty("Message", context.LastError.Message),
new JProperty("Scope", context.LastError.Scope),
new JProperty("Section", context.LastError.Section),
new JProperty("Path", context.LastError.Path),
new JProperty("PolicyId", context.LastError.PolicyId)
).ToString();
return returnResponse.ToString();
}
</trace>
<return-response>
<set-status code="500" reason="Error" />
<set-body>
@{
var debuggingVariable = context.Variables.GetValueOrDefault<string>("debugging");
if(debuggingVariable == "1")
{
var returnResponse = new JObject
(
new JProperty("Authenticated", false),
new JProperty("Source", context.LastError.Source),
new JProperty("Reason", context.LastError.Reason),
new JProperty("Message", context.LastError.Message),
new JProperty("Scope", context.LastError.Scope),
new JProperty("Section", context.LastError.Section),
new JProperty("Path", context.LastError.Path),
new JProperty("PolicyId", context.LastError.PolicyId)
).ToString();
return returnResponse.ToString();
}
else
{
var returnResponse = new JObject(new JProperty("Authenticated", false)).ToString();
return returnResponse.ToString();
}
}
</set-body>
</return-response>
</on-error>

该策略执行以下操作:

入境

  • 自始至终写一些跟踪语句
  • 从查询字符串中获取几个参数以用于策略
  • 删除了几个参数,因为我们无法将这些参数传递给后端服务,因为调用与方法签名不匹配

后端 - 发送请求

  • 使用已传递但显然没有我们删除的参数的现有 URL 向后端服务发送请求
  • 将方法设置为 POST
  • 使用另一个参数设置消息正文

出站

  • 如果我们收到 200 响应,那么我们就知道后端服务正常运行
  • 设置一个名为microservice-response的变量来存储来自后端服务的响应
  • 设置将在生产中删除的调试变量。这样测试人员就可以得到更详细的信息。我们会把microservice-response的内容展示给他们
  • 如果后端服务出现问题(不是 200 响应)则抛出错误

出现错误

  • 当 APIM 捕获错误时。从 context.LastError 变量中提取所有细节,如果处于 Debug模式则发送给调用者

这里是一个 context.LastError 的例子: enter image description here

我希望这对某人有所帮助,因为我花了很长时间才达到这一点。这方面的文档很好,但没有太多内容

关于azure-api-management - 将传入的 GET 请求转换为后端服务的 POST 请求的 APIM 策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39503325/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com