诚然,随着域名/链接在现代互联网中越来越被淡化,大家越来越不在意你的域名和访问的路径,但是我们仍注意到在一些场景中,例如推送通知或者发送短信,里面需要嵌入链接。我们可以看到市面上有各种各样的短链接服务,当然也有附加在这些服务上的,或者是跳转页面包含广告,或者用户无法将这个短链接和你们的业务联系在一起,这时我们就可以考虑自建一个短链接服务。
本文将使用API Gateway和DynamoDB来搭建一个短链接服务,该架构并没有使用Lambda,搭建较容易。
首先我们拆解一下我们可能需要的接口。
- POST,可以让我们的管理员传入原始链接,希望的短链以及标识管理员的身份
- GET,最终用户访问对应的短链接时,会返回给它302并且在Location Header里面包含原始链接
接下来将以最简单的方式构建这个系统,第一个部分是DyanmoDB。
1. 我们需要创建DynamoDB的表,
如上图所示,我们用URL-Shortener作为表名,使用shortKey作为短链接的自定义部分,其余的保持默认。2. 我们需要创建对应的Role,Service选择API Gateway
3. 简单起见,创建好这个Role后,我们为它添加一个in-line的Policy,来指定具体的DyanmoDB
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws-cn:dynamodb:cn-northwest-1:2313xxxx5197:table/URL-Shortener"
}
]
}
接下来我们创建API。
1. 打开API Gateway,我们创建一个REST API,如下图,我们不需要Sample API
2. 以 https://sample.com/shortKey 为例,GET请求应该落在根路径上,诚然我们也可以将POST放在根路径上,但是此处我们出于安全考虑,随机生成一个路径,并且日后也可以单独对这个路径进行进一步鉴权。
3. 接下来,我们在这个新创建的路径下,创建Method
集成的类型为AWS的服务,区域在宁夏,服务为DynamoDB,注意服务访问DynamoDB的方法为POST,实际的Action为UpdateItem,这里的Execution Role就是我们在IAM创建的最小权限的Role。
4. 创建后的页面如下
5. 我们点击Integration Request,在最下面的Mapping Templates里面新增
{ "TableName": "URL-Shortener",
"ConditionExpression": "attribute_not_exists(shortKey)",
"Key": {
"shortKey": {
"S": $input.json('$.shortKey')
}
},
"ExpressionAttributeNames": {
"#l": "originalURL",
"#o": "owner"
},
"ExpressionAttributeValues": {
":l": {
"S": $input.json('$.originalURL')
},
":o": {
"S": $input.json('$.owner')
}
},
"UpdateExpression": "SET #l = :l, #o = :o",
"ReturnValues": "ALL_NEW"
}
attribute_not_exists用来判断当前shortKey是否已经使用,其他的部分则是将请求的JSON映射后存入。
6. 创建好Request后,我们点开Integration Response,也创建一个映射
#set($DDBResponse = $input.path('$'))
{
"shortKey": "$DDBResponse.Attributes.shortKey.S",
"originalURL": "$DDBResponse.Attributes.originalURL.S",
"owner": "$DDBResponse.Attributes.owner.S"
}
这个映射就比较简单,直接将DynamoDB的返回给客户即可。
7. 我们可以点击TEST,构造一个BODY测试一下
{
"originalURL": "https://jinshuju.net",
"owner": "Sean",
"shortKey": "jsj"
}
可以看到已经提交成功,此时我们也可以在DynamoDB里面确认一下。
接下来我们制作用户访问对应的shortKey跳转的过程。1. 我们要在根路径下创建资源,注意此时需要资源路径为{shortKey}
2. 在这个资源下创建Method,GET
注意API GW调DynamoDB时为POST
3. 修改Integration Request的Mapping为下图
即从Path里提取shortKey,传给DynamoDB
{
"Key": {
"shortKey": {
"S": "$input.params().path.shortKey"
}
},
"TableName": "URL-Shortener"
}
4. 我们需要先在Method Response中,删除200,因为这里我们要返回302,所以我们删除后添加302,同时要添加Location头
5. 我们回到Integration Response,删除原来的200对应的Response,重新添加302,并且添加Mapping Template
#set($DDBResponse = $input.path('$'))
#if ($DDBResponse.toString().contains("Item"))
#set($context.responseOverride.header.Location = $DDBResponse.Item.originalURL.S)
#end
6.我们测试一下
后续
- 你可以添加自定义域名,以真正实现短链接服务
- 你可以在API GW前增加WAF