Serverless 架构应用开发指南:创建自己的 Serverless 短链服务
2017-11-12 15:12
1126 查看
在想用 Serverless 可以做点什么简单的在线应用后,我想到了一个是在线短链生成服务。最后的结果见:http://x.pho.im/,一个非常简单的在线应用。
这里的代码基于:https://github.com/vannio/serverless-shrink。
因为上面的代码中,不能自动创建域名。然后,再针对数据库进行了一些优化。
创建短链时,使用生成一个四位的字符串
将原有的 URL 和生成的 URL 存储到 DynamoDB 中
在返回的 HTML 中,输出对应的 URL
重定向时,从 DynamoDB 读取对应的短链
如果短链存在,则执行 302 重定向;如果不存在,则返回一个 404。
当我们提交的时候,就会触发对应的 POST 请求。
解析出提交表单中的链接
根据 URL 生成对应的短链
将对应的 URL 和短链的对应关系存储到 DynamoDB 中
如果成功,则返回生成的短链;失败则,返回一个 400
事实上,在存储 URL 和短链的 map 之前,我们应该先判断一下数据中是否已经有相应的短链。不过,对于这种只针对于我一个用户的短链服务来说,这个步骤有点浪费钱——毕竟要去扫描一遍数据库。所以,我也不想去添加这样的扩展功能。
接下来,让我们回到代码中去,代码的主要逻辑都是在 Promise 里,按顺序往下执行。
由于生成的伪随机码是 Buffer 类型,因此需要转换为字符串。同时,因为生成的短链中不应该有 “=+/”,它会导致生成的 URL 有异常。于是,我们便替换掉伪随机码中的这些特殊字体。最后,截取生成的字符串的前 4 位。
现在,我们就可以将其存储到数据中了。
最后,我们返回了
其中的 HTML 部分的渲染逻辑如下所示:
是的,只是返回短链和原有的链接了。
好了,现在我们已经拥有这个短链了。接下来,就是点击这个短链,看看背后会发生些什么?
然后,从数据库中按短链的 slug 查找对应的 URL:
如果存在对应的短链,则 302 重定向对原有的 URL:
如果没有,则返回一个 404。
我们的代码就是这么的简单,现在让我们来部署测试一下。
然后执行
如果你在 Route53 上注册有相应的域名,修改一下
紧接着,执行
一切准备就绪了。
访问 https://x.pho.im/
然后输入一个链接,如:https://github.com/phodal/serverless-guide
复制生成的地址:https://x.pho.im/rgQC,并返回
看是否会重定向到我们的网站上。
Done!
这里的代码基于:https://github.com/vannio/serverless-shrink。
因为上面的代码中,不能自动创建域名。然后,再针对数据库进行了一些优化。
代码逻辑
这里的代码逻辑比如简单:创建短链时,使用生成一个四位的字符串
将原有的 URL 和生成的 URL 存储到 DynamoDB 中
在返回的 HTML 中,输出对应的 URL
重定向时,从 DynamoDB 读取对应的短链
如果短链存在,则执行 302 重定向;如果不存在,则返回一个 404。
创建首页
首页只是一个简单的 HTML 表单:const base_page = `<html> <h1>Hi!</h1> <form method="POST" action=""> <label for="uri">Link:</label> <input type="text" id="link" name="link" size="40" autofocus /> <br/> <br/> <input type="submit" value="Shorten it!" /> </form> </html>` module.exports.handler = (event, context, callback) => { console.log(JSON.stringify(event)); callback( null, { statusCode: 200, body: base_page, headers: {'Content-Type': 'text/html'}, } ); }
当我们提交的时候,就会触发对应的 POST 请求。
生成短链
如上所述,对于个短链请求,我们要做这么几件事:解析出提交表单中的链接
根据 URL 生成对应的短链
将对应的 URL 和短链的对应关系存储到 DynamoDB 中
如果成功,则返回生成的短链;失败则,返回一个 400
事实上,在存储 URL 和短链的 map 之前,我们应该先判断一下数据中是否已经有相应的短链。不过,对于这种只针对于我一个用户的短链服务来说,这个步骤有点浪费钱——毕竟要去扫描一遍数据库。所以,我也不想去添加这样的扩展功能。
接下来,让我们回到代码中去,代码的主要逻辑都是在 Promise 里,按顺序往下执行。
解析出提交表单中的链接
首先,我们通过querystring库来解决中表单中的链接。
const submitted = querystring.parse(event.body).link;
根据 URL 生成对应的短链
接着,使用 Node.js 中的crypto.randomBytes方法来生成八位的伪随机码。
crypto.randomBytes(8) .toString('base64') .replace(/[=+/]/g, '') .substring(0, 4)
由于生成的伪随机码是 Buffer 类型,因此需要转换为字符串。同时,因为生成的短链中不应该有 “=+/”,它会导致生成的 URL 有异常。于是,我们便替换掉伪随机码中的这些特殊字体。最后,截取生成的字符串的前 4 位。
现在,我们就可以将其存储到数据中了。
存储到 Dynamo 数据库中。
对应的存储逻辑如下所示,我们 new 了一个 DocumentClient 对象,然后直接存储到数据库中。put函数中的对象,即是对应的参数。
return docClient.put({ TableName: tableName, Item: { slug: slug, url: submitted }, Expected: { url: {Exists: false} } }).promise().then(() => { return slug; });
最后,我们返回了
slug,用于接下来的处理。
返回短链给用户
一切处理正常的话,我们将向用户返回最后的内容:return callback( null, { statusCode: 200, body: RenderPage(path.join(prefix, slug).replace(':/', '://'), prefix), headers: {'Content-Type': 'text/html'} } );
其中的 HTML 部分的渲染逻辑如下所示:
function RenderPage (link, submitted) { return ` <html> <body> <h3> <a href="${link}">${link}</a> </h3> <p>URL ${submitted} was shortened to: <a href="${link}">${link}</a> </p> </body> </html>` };
是的,只是返回短链和原有的链接了。
好了,现在我们已经拥有这个短链了。接下来,就是点击这个短链,看看背后会发生些什么?
重定向短链
首先,我们先在我们的serverless.yml中,将短链的路径配置为参数:
functions : ... redirect: handler: redirect/index.handler events: - http: path: /{slug} method: get
然后,从数据库中按短链的 slug 查找对应的 URL:
const slug = event.pathParameters.slug; docClient.get({ TableName: tableName, Key: { slug: slug } }, (err, data) => { })
如果存在对应的短链,则 302 重定向对原有的 URL:
const item = data.Item; if (item && item.url) { callback( null, { statusCode: 302, body: item.url, headers: { 'Location': item.url, 'Content-Type': 'text/plain' } } ) }
如果没有,则返回一个 404。
我们的代码就是这么的简单,现在让我们来部署测试一下。
部署及测试短链服务
如果你还没有 clone 代码的话,执行下面的命令来安装:serverless install -u https://github.com/phodal/serverless-guide/tree/master/url-shorter -n url-shorter
然后执行
yarn install来安装对应的依赖。
如果你在 Route53 上注册有相应的域名,修改一下
serverless.yml文件中的域名,我们就可以使用
serverless create_domain来创建域名的路由。
紧接着,执行
serverless deploy来部署。
api keys: None endpoints: GET - https://4rr5ndhaw3.execute-api.us-east-1.amazonaws.com/dev/ POST - https://4rr5ndhaw3.execute-api.us-east-1.amazonaws.com/dev/ GET - https://4rr5ndhaw3.execute-api.us-east-1.amazonaws.com/dev/{slug} functions: main: url-shorter-dev-main create: url-shorter-dev-create redirect: url-shorter-dev-redirect Serverless Domain Manager Summary Domain Name x.pho.im Distribution Domain Name d2s4y0p5nuw3k7.cloudfront.net Serverless: Removing old service versions...
一切准备就绪了。
访问 https://x.pho.im/
然后输入一个链接,如:https://github.com/phodal/serverless-guide
复制生成的地址:https://x.pho.im/rgQC,并返回
看是否会重定向到我们的网站上。
Done!
相关文章推荐
- Serverless 应用开发指南:基于 Serverless 与 Lambda 的微信公共平台
- 下一代应用开发的创新方式 Serverless架构实践
- Serverless 应用开发指南:serverless 的 hello, world
- 讯飞语音开发基础——创建应用以及开通服务
- Kurento应用开发指南(以Kurento 5.0为模板) 之五:kurento架构
- IOS开发创建开发证书及发布App应用指南
- 纪念日:服务构件环境(SCE)挑起企业级架构的栋梁,下一代的应用开发模式日渐清晰
- #文末福利|云栖大会门票限时赠送# 10.11云栖大会Clouder Lab “十分钟搭建共享应用”,手把手教你Serverless架构下的应用实现
- ASP.NET ZERO 学习 —— (11) 应用开发Demo之创建应用服务
- 使用Apworks开发基于CQRS架构的应用程序(六):创建.NET WCF服务
- 用 Docker 创建 serverless 应用
- Knockout应用开发指南 第五章:创建自定义绑定
- Serverless架构 - 用服务代替服务器
- Knockout应用开发指南 第五章:创建自定义绑定
- 【OSChina-MoPaaS应用开发大赛】地理信息服务平台 GisServer
- Google 官方推出应用开发架构指南
- 纪念日:服务构件环境(SCE)挑起企业级架构的栋梁,下一代的应用开发模式日渐清晰
- Kurento应用开发指南(以Kurento 5.0为模板) 之五:kurento架构
- 文末福利|云栖大会门票限时赠送# 10.11云栖大会Clouder Lab “十分钟搭建共享应用”,手把手教你Serverless架构下的应用实现
- Kurento应用开发指南(以Kurento 6.0为模板) 之六:kurento架构