原文链接:https://dev.to/kumo/how-to-rename-api-gateway-path-parameters-on-aws-20fa 作者:Kumo
无论你使用的是使用 aws-apigateway (v1) 模块的 REST API 还是使用 aws-apigatewayv2 (v2) 的 HTTP API,重命名 AWS API Gateway 中的路径参数都可能是一项复杂的任务。在本文中,我们将探讨重命名两个模块的路径参数的过程,并讨论两种解决方案,以实现所需的结果而不会对用户造成干扰。
REST API 代码 (v1)
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
const getArticle = new lambda.Function(this, 'GetArticle', {
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('path/to/getArticle/code'),
});
const restApi = new apigateway.RestApi(this, 'MyRestApi');
restApi.root
.resourceForPath('/get-article/{id}')
.addMethod('GET', new apigateway.LambdaIntegration(getArticle));
HTTP API 代码 (v2)
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigatewayv2 from 'aws-cdk-lib/aws-apigatewayv2';
import * as integrations from 'aws-cdk-lib/aws-apigatewayv2-integrations';
const getArticle = new lambda.Function(this, 'GetArticle', {
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('path/to/getArticle/code'),
});
const httpApi = new apigatewayv2.HttpApi(this, 'MyHttpApi');
httpApi.addRoutes({
path: '/get-article/{id}',
methods: ['GET'],
integration: new integrations.LambdaProxyIntegration({
handler: getArticle,
}),
});
让我们考虑一个场景,你不仅需要通过文章检索文章id
,还需要根据其与时事通讯的关联来检索文章。在这种情况下,你希望将端点路径从 修改/get-article/{id}
为/get-article/{newsletterId}/{articleId}
。尽管此更改纯粹是语义上的,但你可以将 的值分配给id
并newsletterId
引入一个名为 的新参数articleId
。
为了简化问题,让我们重点关注将参数重命名id
为 的目标articleId
。
然而,实施此更新并不像最初看起来那么简单。当你尝试使用 部署更改时npx cdk deploy
,你将遇到以下错误消息:
- 对于 REST API (v1)
Resource handler returned message: "A sibling ({id}) of this resource already has a variable path part -- only one is allowed (Service: ApiGateway, Status Code: 400, ...
- 对于 HTTP API (v2)
Resource handler returned message: "The provided route key "GET /get-article/{articleId}" has a conflicting variable on the same hierarchical level as "GET /get-article/{id}" (Service:
AmazonApiGatewayV2; Status Code: 409; Error Code: ConflictException;
重命名 API 路径参数主要有两种解决方案。
解决方案 1:评论、部署、更新和重新部署
优点:简单且易于实施。
缺点:如果在生产中使用该路由,则需要为用户提供维护窗口和停机时间。
- 注释掉包含旧路径参数的 API 资源。
// restApi.root
// .resourceForPath('/get-article/{id}')
// .addMethod('GET', new apigateway.LambdaIntegration(getArticle));
- 使用 部署更改
npx cdk deploy
。 - 取消前面注释的代码,并将路径参数名称从 修改
id
为articleId
。
restApi.root
.resourceForPath('/get-article/{articleId}')
.addMethod('GET', new apigateway.LambdaIntegration(getArticle));
- 使用 再次部署更改
npx cdk deploy
。
通过遵循这种方法,你可以有效地更新路径参数,而无需直接重命名它。但是,请注意部署窗口期间可能导致的停机时间。
注意:另一种方法是从 AWS 控制台手动删除相应的资源。虽然此方法在某些情况下可能会成功,但不建议这样做,因为它可能会给 CDK 堆栈带来潜在的复杂性。
解决方案 2:创建并迁移到新资源
优点:用户无需停机。
缺点:需要临时维护两个资源,并且需要更新客户端代码才能从旧资源迁移到新资源。
要使用此方法重命名路径参数,请按照下列步骤操作:
- 使用新路径创建新资源,但保持与旧资源相同的集成和方法。(例如,
/get-article/v2/{articleId}
)。
restApi.root
.resourceForPath('/get-article/{id}')
.addMethod('GET', new apigateway.LambdaIntegration(getArticle));
// Add a new resource with the new path parameter name
restApi.root
.resourceForPath('/get-article/v2/{articleId}')
.addMethod('GET', new apigateway.LambdaIntegration(getArticle));
- 通过更新客户端代码以使用新的路径参数名称,从旧资源迁移到新资源。迁移完成后,你可以安全地删除旧资源。
- (可选)重命名新资源以匹配旧资源的名称,但使用新的路径参数名称 (
/get-article/{articleId}
)。确保客户端代码相应更新。
// Remove these lines
// restApi.root
// .resourceForPath('/get-article/{id}')
// .addMethod('GET', new apigateway.LambdaIntegration(getArticle));
restApi.root
// Remove the `/v2` suffix
.resourceForPath('/get-article/{articleId}')
.addMethod('GET', new apigateway.LambdaIntegration(getArticle));
该解决方案保证为你的用户提供不间断的服务。但是,它涉及临时管理两个资源并协调迁移过程与客户端更新。
结论
通过执行以下步骤,你可以成功重命名 AWS 上的 API Gateway 中的路径参数。
强烈推荐第二种解决方案,因为它稳健且具有避免用户停机的优点。但是,如果你很赶时间或者你的生产环境没有活跃用户,那么第一个解决方案也是一个值得考虑的可行选择。
关于Apifox
- 集成了API 文档、API 调试、API Mock、API 自动化测试 API 一体化协作平台
- 拥有更先进的 API 设计/开发/测试工具
- Apifox = Postman + Swagger + Mock + JMeter
点击这里,开始 在线使用 Apifox