Azure 无服务器函数入门





5.00/5 (5投票s)
2019 年 3 月 10 日
11分钟阅读

20116

169
通过在 Azure 上创建一个地理编码函数,
本文是 CodeProject 无服务器函数挑战赛的一部分。
引言
欢迎!在本教程中,我们将使用 Azure Functions 创建一个简单而有趣的 HTTP API。
如果您是无服务器的新手,并且想知道这一切到底是怎么回事,我建议您花几分钟阅读我的介绍性文章。在那里,我概述了无服务器是什么以及为什么“无服务器”这个名称可能不像您想象的那么糟糕。
入门
如果您还没有 Azure 帐户,则需要先创建一个。 单击此处跳转到 Azure 帐户创建页面。
您需要一张信用卡才能创建免费试用帐户,即使您不会被收费。我知道这有点烦人,但所有云提供商都这样做是为了防止人们通过创建新的电子邮件地址来获得无限数量的免费试用。
如果您已经有一个 Azure 帐户,Functions 服务有一个永不过期的免费层,因此您将能够完成本教程而不会产生任何费用。
登录 Azure 门户后,您可以单击“创建资源”,然后单击“计算”,然后单击“函数应用”来创建您的第一个无服务器函数。
接下来,您将看到此屏幕,要求您填写有关您的应用程序的一些信息。
首先为您的函数应用选择一个名称。由于它将托管在 azurewebsites.net 域上,因此您需要选择一个其他人没有使用过的名称。
接下来,您需要创建一个新的资源组。将资源组视为一个方便的容器,它将应用程序的所有部分捆绑在一起。当您的应用程序变得更大时,这很有帮助,因为您可以确保与您的应用程序相关的所有函数、权限和其他设置都保存在一个逻辑包中,从而使它们易于监控和管理。
默认情况下,Azure 会尝试使用您的应用程序名称作为资源组名称。除非您有理由不这样做,否则我建议坚持使用此名称。
对于其余设置,请使用上图中所示的设置:Windows 操作系统、消耗计划、美国中部作为位置,以及 JavaScript 作为运行时堆栈。让 Azure 为您的函数应用创建新的存储。
完成所有这些操作后,单击“创建”。Azure 将弹出一条通知,告诉您部署正在进行中。如果您单击屏幕顶部的通知图标,您将看到应用程序的部署状态。
部署完成后,通知将更新以告知您。
单击“转到资源”按钮,您将进入函数应用的仪表板。
所以我们现在有一个函数应用,但我们还没有向其中添加任何实际的函数。让我们解决这个问题!在应用程序仪表板上,单击“+ 新建函数”按钮。这将打开一个对话框,要求您选择开发环境。
选择“门户内”选项。这样,您无需在计算机上安装任何东西即可启动并运行无服务器应用程序。
在实际场景中,当您处理包含许多函数的无服务器应用程序时,您可能希望使用 Visual Studio、VS Code 或您选择的其他文本编辑器或 IDE。但对于像我们这样的小项目,使用门户内编辑器可以使应用程序创建过程快速简便!
选择了开发环境后,Azure 会要求我们选择所需的函数类型。
选择“Webhook + API”。这将为我们提供一个设置为响应 HTTP 请求的函数。选择此选项后,Azure 将创建您的函数,用一些默认代码填充它,并将您发送到新函数的代码编辑器。
如果您想查看实际运行的默认代码,请单击“获取函数 URL”链接。复制提供的链接,将其粘贴到新的浏览器选项卡中,然后加载它。
您会注意到您的函数会抱怨您需要提供一个名称作为查询字符串的一部分。
如果您查看 URL,您会注意到它已经包含一个名为“code”的查询参数。默认情况下,Azure 会为每个无服务器函数生成一个访问代码,以防止未经授权的访问。
虽然您希望为生产应用程序添加更复杂的访问控制策略,但 Azure 生成的访问代码非常适合我们的第一个无服务器函数,因为我们只是为自己创建它。
由于 URL 已经有一个查询字符串,只需附加
&name=Bob
到浏览器中的 URL 末尾,然后按 Enter。这次,函数会向 Bob 打招呼!
这样,我们就创建了一个无服务器应用程序,它正在运行并响应 HTTP 请求。请注意我们**不需要**做的所有事情:我们不需要安装 Node.js、Web 服务器或 Web 框架。我们填写了一张简短的表格,点击了几下,最终得到了一个功能齐全的 Web 应用程序。
自定义代码
现在我们已经有了函数,让我们让它做一些有用的事情!
我们将把我们的无服务器函数变成一个地理编码服务——它将接受一个包含街道地址的 POST 请求,并返回该街道地址的一组地图坐标。
为此,我们需要使用 Azure Maps。与 Azure Functions 一样,Azure Maps 也有一个免费层,我们将利用它。要使用 Azure Maps,我们需要在 Azure 门户中创建一个新资源。
首先单击“创建资源”,然后在搜索框中输入“Maps”。
在出现的下拉框中,单击“Maps”。这将弹出一个包含有关 Maps 服务的更多信息的屏幕。单击此屏幕上的“创建”按钮继续。
这将带您进入 Azure Maps 帐户创建屏幕。如您所见,它将与您的免费试用帐户或您在开始此练习之前已有的现有 Azure 帐户关联。
将地图帐户添加到您已为函数应用创建的资源组中。为您的地图帐户选择一个名称。任何名称都可以!
对于定价层,选择“标准 S0”。此层将完成我们需要的一切,并且我们的使用将属于 Azure Maps 的免费层。
完成后,单击“创建”,Azure 会将 Maps 资源添加到您的资源组。准备就绪后,您将进入概述页面。
单击“转到资源”按钮,这将带您进入地图帐户的仪表板。
单击“设置”下的“身份验证”菜单项。这将显示我们很快会需要的一些信息。
就本次练习而言,您需要注意的值是主密钥。将其复制到某处,或将地图身份验证屏幕留在浏览器选项卡中,因为您很快就会需要它!
创建地图帐户后,是时候创建一个无服务器函数了,它可以将地址转换为经纬度——事实证明,还可以转换为许多其他信息!
通过单击 Azure 门户菜单中的“函数应用”项加载您的函数应用,然后单击您之前创建的应用程序以加载其仪表板。我们将创建一个新函数来处理我们的映射功能。
在您的应用程序仪表板中,单击“函数”菜单项旁边的“+”图标。
当要求选择函数类型时,选择 HTTP 触发器。
为新函数提供您喜欢的任何名称,并将其授权级别设置为 Function。
单击“创建”,您将进入新函数的代码。它将包含您之前看到的相同默认代码。首先擦除所有默认代码,以便您留下一个空白的代码编辑器。
接下来,将其替换为以下代码:
const https = require("https");
const apiVersion = 1.0;
const mapsKey = "your maps key goes here";
const request = (url) => {
return new Promise((resolve, reject) => {
https.get(url, (resp) => {
let data = "";
resp.on("data", (chunk) => {
data += chunk;
});
resp.on("end", () => {
const res = JSON.parse(data)
resolve(res);
});
}).on("error", (err) => {
reject(err);
});
});
}
module.exports = async function (context, req) {
if (req.query.address) {
const url = `https://atlas.microsoft.com/search/fuzzy/json?api-version=${apiVersion}&subscription-key=${mapsKey}&query=${req.query.address}`;
try {
const data = await request(url);
context.res = {
status: 200,
body: data.results
};
} catch(err) {
context.res = {
status: 500,
body: err
}
}
context.done();
} else if (req.query.memberId) {
const url = `https://cdprj-sc.azurewebsites.net/api/GetCode?memberId=${req.query.memberId}`;
const data = await request(url);
if (data) {
context.res = {
body: data.result
};
context.done();
}
}
else {
context.res = {
status: 400,
body: "Please pass an address as part of the query string."
};
}
};
您需要进行一项更改:在代码第三行的 `mapsKey` 变量中,粘贴您的地图帐户的主密钥值。
让我们稍微看一下代码,看看发生了什么。我们首先创建一个辅助函数,它将 Node.js `https` 库包装在一个 Promise 中。这使我们以后的工作更轻松,因为我们可以将此请求函数与 JavaScript 方便的 `await` 关键字一起使用。
接下来,我们导出一个 `async` 函数,它处理我们的无服务器函数收到的请求,并返回响应。
它检查查询字符串中是否收到了 `address`,如果没有收到则向用户抱怨。
如果收到了地址,则该函数会构建一个向 Azure Maps 服务发出请求的 URL。请注意,我们包含三个查询参数:API 版本、订阅密钥和查询。我们将 Azure Maps 密钥作为 `subscription-key` 传入,并将我们正在查找的地址作为 `query` 传入。
我们的代码然后向 Azure Maps 发出请求。如果我们得到结果,我们输出它。如果我们得到错误,我们输出错误。
细心的读者会注意到,其中还有一些代码检查名为 `memberId` 的查询字符串参数。这是一段超级秘密的代码,我们稍后将使用它来为无服务器挑战生成一个入口代码。
要测试您的函数,请单击“获取函数 URL”链接获取函数的 URL。
将其粘贴到浏览器中,并通过在 URL 末尾附加 `&address=157 Awesome St.` 向查询字符串末尾添加一个 `address` 项。不过,请选择一个真实的地址。尝试您自己的地址,看看会弹出什么。它看起来像这样:
https://my-awesome-app.azurewebsites.net/api/Mapper?code=abcdefg==&address=30 Yonge St, Toronto, ON
如您所见,我调用了我的无服务器函数,并要求它查找冰球名人堂的地址。此调用返回的结果如下:
[
{
"type": "Point Address",
"id": "CA/PAD/p0/3907925",
"score": 9.894,
"address": {
"streetNumber": "30",
"streetName": "Yonge Street, Heritage Highway",
"municipalitySubdivision": "Toronto, Downtown Toronto, Church-Yonge Corridor, Bay Street Corridor",
"municipality": "Toronto",
"countryTertiarySubdivision": "Toronto",
"countrySubdivision": "ON",
"postalCode": "M5E",
"extendedPostalCode": "M5E1X8",
"countryCode": "CA",
"country": "Canada",
"countryCodeISO3": "CAN",
"freeformAddress": "30 Yonge Street, Toronto, ON M5E1X8",
"countrySubdivisionName": "Ontario"
},
"position": {
"lat": 43.64694,
"lon": -79.37712
},
"viewport": {
"topLeftPoint": {
"lat": 43.64784,
"lon": -79.37836
},
"btmRightPoint": {
"lat": 43.64604,
"lon": -79.37588
}
},
"entryPoints": [
{
"type": "main",
"position": {
"lat": 43.64699,
"lon": -79.37698
}
}
]
}
]
您会看到,除了经纬度之外,Azure Maps 还返回了许多其他信息!
在有人提供地址但忘记添加邮政编码的情况下,您可以使用 Azure Maps 查找它。
比赛验证
早些时候,我们注意到我们的无服务器函数中有一段代码用于检查 `memberId` 查询参数。
此代码获取您的 CodeProject 会员 ID,并将其发送到 CodeProject 自己的无服务器函数,然后该函数将为您提供一个比赛参赛代码。没错!CodeProject 正在使用无服务器函数来生成一个比赛的参赛代码,该比赛教您如何制作无服务器函数。这完全是无服务器的。
首先,您需要您的 CodeProject 会员 ID。您可以在您的 CodeProject 个人资料页面上找到它,您可以通过登录 CodeProject 并单击屏幕右上角附近的用户名为访问该页面。
在您的个人资料页面上,您会在右侧看到一个框,其中包含您的会员编号和您的照片。这是我的个人资料页面,我的会员编号用红色框起来,方便查看。
现在,您将发出一个与您之前向函数发送地址进行地理编码的请求非常相似的请求。只是这次您将发送您的会员编号。
您需要做的就是获取您用于发送地址的 URL,删除末尾的地址,然后添加您的会员 ID。对我来说,它看起来像这样:
https://my-awesome-app.azurewebsites.net/api/Mapper?code=abcdefg==&memberId=12303349
它将返回一个看起来像这样的结果:
Hello there, member 12303349, your entry code is 123456789
不,这不是我的真实参赛代码。即使是,它也只对我有效。您必须使用自己的!
复制参赛代码,然后前往此处的代码输入页面输入您的代码。
结论
至此,我们的无服务器教程结束了。我们已经在 Azure 上创建了一个无服务器函数应用,并将其与 Azure Maps 连接起来进行地理编码。
而且我们才刚刚开始!您可以设置无服务器函数来响应云提供商内部发生的事件。您绝对不限于响应 HTTP 请求。您可以拥有在文件上传、数据库条目创建或大量其他事件发生时触发的函数。以下是一些链接,可帮助您了解更多有关多个云提供商上无服务器函数触发器的信息:
撰写文章
现在您已经完成了,是时候为无服务器挑战赛撰写您自己的文章了。有丰厚的奖品等你来赢取!
也许您可以展示如何使用无服务器函数来接收视频上传并将其转码为不同的格式。
或者您可以编写一个完整的无服务器应用程序,带有 Angular 或 React 前端,并由 Azure SQL 数据库、CosmosDB 或 AWS DynamoDB 提供支持。
可能性是无限的!何不提出一个很棒的想法,与世界分享,也许还能赢取奖品呢?