使用AWS Lambda在Go中构建RESTful API

在本文中,我们将学习使用AWS Lambda在Go中设计,构建和部署RESTful API。 在开始之前,让我给您简要介绍一下AWS Lambda。

什么是AWS Lambda?
AWS Lambda是一种无服务器计算服务,可运行我们的代码以响应事件并自动为我们管理基础计算资源。 我们可以使用AWS Lambda通过自定义逻辑扩展其他AWS服务,或者创建我们自己的后端服务,这些后端服务以AWS规模,性能和安全性运行。 AWS Lambda可以自动运行代码以响应多个事件,例如通过Amazon API Gateway发出的HTTP请求,对Amazon S3存储桶中的对象的修改,Amazon DynamoDB中的表更新以及AWS Step Functions中的状态转换。

Lambda在高可用性计算基础架构上运行我们的代码,并执行所有计算资源管理,包括服务器和操作系统维护,容量配置和自动缩放,代码和安全补丁部署以及代码监视和日志记录。 我们需要做的就是提供代码。

现在,让我们开始构建一个API,该API将帮助本地电影租赁店管理其可用电影。

API架构

下图显示了API Gateway和Lambda如何适应API体系结构:

RESTful API

AWS Lambda支持微服务开发。 话虽如此,每个端点都会触发不同的Lambda函数。 这些功能彼此独立并且可以用不同的语言编写,从而导致在功能级别上进行缩放,更易于进行单元测试以及松散耦合。

来自客户端的所有请求都首先通过API网关。 然后,它将传入的请求相应地路由到正确的Lambda函数。

请注意,单个Lambda函数可以处理多种HTTP方法( GETPOSTPUTDELETE等)。 建议为每个功能创建多个Lambda函数,以利用微服务的功能。 但是,构建单个Lambda函数来处理多个端点可能是一个不错的练习。

端点设计

现在已经定义了体系结构,是时候完成上图中描述的功能的实现了。 您可以使用net / http Go包并使用内置的状态代码变量,例如http.StatusOKhttp.StatusCreatedhttp.StatusBadRequesthttp.StatusInternalServerError等 ,而不是对HTTP状态代码进行硬编码。

GET方法

要实现的第一个功能是列出电影。 这就是GET方法起作用的地方。 让我们从以下步骤开始:

步骤1:创建注册了findAll处理程序的Lambda函数。 该处理程序将电影列表转换为字符串,然后返回由APIGatewayProxyResponse变量包装的字符串以及200 HTTP状态代码。 如果转换失败,它也会处理错误。 处理程序的实现如下:

package mainimport ("encoding/json""github.com/aws/aws-lambda-go/events""github.com/aws/aws-lambda-go/lambda"
)var movies = []struct {ID int `json:"id"`Name string `json:"name"`
}{{ID: 1,Name: "Avengers",},{ID: 2,Name: "Ant-Man",},{ID: 3,Name: "Thor",},{ID: 4,Name: "Hulk",}, {ID: 5,Name: "Doctor Strange",},
}func findAll() (events.APIGatewayProxyResponse, error) {response, err := json.Marshal(movies)if err != nil {return events.APIGatewayProxyResponse{}, err}return events.APIGatewayProxyResponse{StatusCode: 200,Headers: map[string]string{"Content-Type": "application/json",},Body: string(response),}, nil
}func main() {lambda.Start(findAll)
}

您可以使用net / http Go包并使用内置的状态代码变量,例如http.StatusOKhttp.StatusCreatedhttp.StatusBadRequesthttp.StatusInternalServerError等 ,而不是对HTTP状态代码进行硬编码。

步骤2:创建一个包含以下内容的脚本文件,以构建Lambda函数部署包,一个包含您的代码和任何依赖项的.zip文件,如下所示:

#!/bin/bashecho "Build the binary"
GOOS=linux GOARCH=amd64 go build -o main main.goecho "Create a ZIP file"
zip deployment.zip mainecho "Cleaning up"
rm main

步骤3:执行以下命令以将部署包构建为.zip文件:

$ chmod +x build.sh
$ ./build.sh

步骤4:使用此处提到的步骤配置AWS CLI。 配置完成后,按照此处提到的步骤创建一个名称为FindAllMoviesRole的AWS角色,并验证是否成功创建该角色:

$ aws iam get-role --role-name FindAllMoviesRole

上面的命令应给出响应,如下面的屏幕快照所示:

RESTful API

步骤5:接下来,使用AWS CLI创建一个新的Lambda函数,如下所示:

aws lambda create-function --function-name FindAllMovies \--zip-file fileb://deployment.zip \--runtime go1.x --handler main \--role arn:aws:iam::ACCOUNT_ID:role/FindAllMoviesRole \--region us-east-1

创建函数后,将为我们提供与以下屏幕快照所示的输出相同的输出:

RESTful API

步骤6 :回到AWS Lambda控制台,您应该看到该函数已成功创建:

RESTful API

步骤7 :创建一个带有空JSON的示例事件,因为该函数不需要任何参数,然后单击Test按钮:

RESTful API

您将在上一个屏幕截图中注意到,该函数以JSON格式返回预期的输出。

步骤8:现在已经定义了函数,您需要创建一个新的API网关来触发它:

RESTful API

步骤9:接下来,从“ 操作”下拉列表中,选择“ 创建资源并将其命名为电影”

RESTful API

步骤10:通过点击Create Method在此/ movies资源上公开GET 方法 。 在“ 集成类型”部分下选择“ Lambda函数 ”,然后选择“ FindAllMovies”函数:

RESTful API

步骤11:要部署API,请从“ 操作”下拉列表中选择“ 部署API ”。 系统将提示您创建一个新的部署阶段:

RESTful API

步骤12:一旦创建了部署阶段,就会显示一个调用URL:

RESTful API

步骤13:将浏览器指向给定的URL或使用现代的REST客户端(例如Postman或Insomnia)。 您可以使用cURL工具,因为默认情况下它已安装在几乎所有操作系统上:

curl -sX GET https://51cxzthvma.execute-api.us-east-1.amazonaws.com/staging/movies | jq '.'

上面的命令将以JSON格式返回电影列表:

RESTful API

调用GET端点时,请求将通过API网关,这将触发findAll处理程序。 这会将API网关代理的响应以JSON格式返回给客户端。

现在已经部署了findAll函数,您可以实现findOne函数以通过其ID搜索电影。

带参数的GET方法

findOne处理程序需要包含事件输入的APIGatewayProxyRequest参数。 然后,它使用PathParameters方法获取影片ID并对其进行验证。

如果提供的ID无效,则Atoi方法将返回错误,并将500错误代码返回给客户端。 否则,将根据索引获取电影,并以包装在APIGatewayProxyResponse中200 OK状态返回给客户端:

...func findOne(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {id, err := strconv.Atoi(req.PathParameters["id"])if err != nil {return events.APIGatewayProxyResponse{StatusCode: 500,Body:       "ID must be a number",}, nil}response, err := json.Marshal(movies[id-1])if err != nil {return events.APIGatewayProxyResponse{StatusCode: 500,Body:       err.Error(),}, nil}return events.APIGatewayProxyResponse{StatusCode: 200,Headers: map[string]string{"Content-Type": "application/json",},Body: string(response),}, nil}func main() {lambda.Start(findOne)}

FindAllMovies函数类似,创建一个新的Lambda函数以搜索电影:

aws lambda create-function --function-name FindOneMovie \--zip-file fileb://deployment.zip \--runtime go1.x --handler main \--role arn:aws:iam::ACCOUNT_ID:role/FindOneMovieRole \--region us-east-1

返回API Gateway控制台,创建一个新资源,公开GET方法,然后将资源链接到FindOneMovie函数。 注意在路径中使用{id}占位符。 id的值将通过APIGatewayProxyResponse对象提供。 以下屏幕截图描述了这一点:

RESTful API

重新部署API,并使用以下cURL命令测试端点:

curl -sX https://51cxzthvma.execute-api.us-east-1.amazonaws.com/staging/movies/1 | jq '.'

将返回以下JSON:

RESTful API

使用ID调用API URL时,如果存在ID对应的影片,则返回该影片。

POST方法

现在,您知道带有和不带有路径参数的GET方法如何工作。 下一步是通过API网关将JSON有效负载传递给Lambda函数。 该代码是不言自明的。 它将输入的请求转换为电影结构,将其添加到电影列表,然后以JSON格式返回新的电影列表:

package mainimport ("encoding/json""strconv""github.com/aws/aws-lambda-go/events""github.com/aws/aws-lambda-go/lambda"
)type Movie struct {ID int `json:"id"`Name string `json:"name"`
}var movies = []Movie{Movie{ID: 1,Name: "Avengers",},...
}func insert(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {var movie Movieerr := json.Unmarshal([]byte(req.Body), &movie)if err != nil {return events.APIGatewayProxyResponse{StatusCode: 400,Body: "Invalid payload",}, nil}movies = append(movies, movie)response, err := json.Marshal(movies)if err != nil {return events.APIGatewayProxyResponse{StatusCode: 500,Body: err.Error(),}, nil}return events.APIGatewayProxyResponse{StatusCode: 200,Headers: map[string]string{"Content-Type": "application/json",},Body: string(response),}, nil
}func main() {lambda.Start(insert)
}

接下来,使用以下命令为InsertMovie创建一个新的Lambda函数:

aws lambda create-function --function-name InsertMovie \--zip-file fileb://deployment.zip \--runtime go1.x --handler main \--role arn:aws:iam::ACCOUNT_ID:role/InsertMovieRole \--region us-east-1

接下来,在/ movies资源上创建一个POST方法,并将其链接到InsertMovie函数:

RESTful API

要对其进行测试,请使用下面的cURL命令以及POST动词和-d标志,后跟JSON字符串(具有id和name属性):

curl -sX POST -d '{"id":6, "name": "Spiderman:Homecoming"}' https://51cxzthvma.execute-api.us-east-1.amazonaws.com/staging/movies | jq '.'

上面的命令将返回以下JSON响应:

RESTful API

如您所见,新电影已成功插入。 如果再次测试,它应该可以按预期工作:

curl -sX POST -d '{"id":7, "name": "Iron man"}' https://51cxzthvma.execute-api.us-east-1.amazonaws.com/staging/movies | jq '.'

前面的命令将返回以下JSON响应:

RESTful API

如您所见,它成功完成并且再次按预期方式插入了影片,但是如果您等待几分钟并尝试插入第三部影片怎么办? 以下命令将用于再次执行它:

curl -sX POST -d '{"id":8, "name": "Captain America"}' https://51cxzthvma.execute-api.us-east-1.amazonaws.com/staging/movies | jq '.'

再次,将返回一个新的JSON响应:

RESTful API

您会发现ID为6和7的电影已被删除; 为什么会这样? 这很简单。 Lambda函数是无状态的。

首次(首次插入)调用InsertMovie函数时,AWS Lambda将创建一个容器并将函数有效负载部署到该容器。 然后,它保持活动状态几分钟,然后终止( 热启动 ),这说明了第二个刀片通过的原因。 在第三个插件中,该容器已经终止,因此Lambda创建一个新容器( 冷启动 )以处理该插件。

这就是为什么以前的状态会丢失的原因。 下图说明了冷/热启动问题:

RESTful API

这就解释了为什么Lambda函数应该是无状态的,为什么您不应该做出任何假设将状态从一次调用保留到另一次调用的假设。

完整的源代码托管在github上 。

翻译自: https://www.javacodegeeks.com/2018/11/build-restful-api-go-using-aws-lambda.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

undertow服务器分析_使用undertow构建和测试Websocket服务器

undertow服务器分析即将发布的JBoss Application Server版本将不再使用Tomcat作为集成的Web服务器,而是将其替换为undertow 。 undertow的体系结构基于可通过Builder API动态添加到服务器的处理程序。 这种方法类似于在Node.js中构造Web服务器的方式。 它使开发人员…

湖北农商行计算机类笔试,2018湖北农商行招聘考试面试考多少分,才能进笔试?...

原标题:2018湖北农商行招聘考试面试考多少分,才能进笔试?昨天,湖北农商行各地农商行面试分数线陆续出来了,恭喜过线的小伙伴,你们顺利的进入了笔试阶段,接下来小编给大家说一下各地的进笔试的分…

计算机共享原理,synchronize底层原理 游戏电脑问题解决分享!

sync1 package com.paddx.test.concurrent;23 public class SynchronizedDemo {4 public void method() {5 synchronized (this) {6 System.out.println("Method 1 start&quot😉;7 }8 }9 }反编译结果:关于这两条指令的作用,我们直接…

单元测试反模式,完整列表

我前段时间写过有关OOP中的反模式的文章 。 现在该写单元测试反模式了,因为它们也存在,并且有很多。 我将尝试在列表中包括我知道的每个示例。 如果您认识其他任何人,请通过请求请求将其添加,或在下面发表评论。 对于每个反模式&a…

功能Java示例 第6部分–用作参数

这是称为“ Functional Java by Example”的系列文章的第6部分。 我在本系列的每个部分中发展的示例是某种“提要处理程序”,用于处理文档。 在前面的部分,我们试图通过移动尽可能多的副作用,如IO,该系统的外部,以使我…

系统属性的JDK 12 Javadoc标记

JDK 12 Early Access Build 20 ( 2018/11/15 )可用,可以用来试用新的Javadoc标签{systemProperty} 。 新的{systemProperty} Javadoc标记在core-libs-dev邮件列表消息“ FYI:用于文档系统属性的新javadoc标记 ”中进行了讨论&…

功能Java示例 第5部分–将I / O移到外部

这是称为“ Functional Java by Example”的系列文章的第5部分。 在上一部分中,我们停止了对文档的变异,并返回了数据的副本。 现在,我们需要移走一些I / O。 如果您是第一次来,最好是从头开始阅读。 它有助于了解我们从何处开始…

实现打包后修改服务器接口地址,vue打包之后生成一个配置文件修改接口

我们的vue代码打包上传到服务器之后,生成一个配置文件,里面可以配置域名或其它什么字段之类的,这样以后换了域名,只修改这个配置文件即可。第一步:安装generate-asset-webpack-plugin插件npm install --save-dev gener…

我的世界无人维护的服务器,我的世界:如何进入9年无人管理的2B2T?全球最大战争服务器!...

原标题:我的世界:如何进入9年无人管理的2B2T?全球最大战争服务器!2b2t因混乱和9年无人管理而闻名于世,目前是全球最大的《我的世界》战争服务器,同时又是第二大Minecraft古老的服务器。​最近很多小伙伴都在…

集团bim对集团项目服务器,BIM再添一员,五洋建设集团BIM项目组举行成立仪式

BIM项目组的成立,标志着五洋建设集团自此迈入了可视化数字建筑信息模型的阵营,掀开了五洋建设集团设计、施工一体化服务新的一页。随后,五洋建筑设计院院长金杭杭主持召开了工作会议。金杭杭院长在致辞中表示,由建设集团技术管理中…

java pojo使用_在POJO中使用ThreadLocal进行Java嵌套事务

java pojo使用大多数嵌套事务是使用EJB实现的,现在我们尝试在POJO上实现嵌套事务。 在这里,我们使用了ThreadLocal的功能。 了解嵌套事务 事务可以嵌套在另一个内部。 因此,内部事务或外部事务可以回滚或提交,而不会影响其他事务…

Java开发人员应该知道的5大Spring Boot功能

您可能已经听说过Spring Boot,这是用不到140个字符创建一个Spring Web应用程序的神奇力量,可以在一条推文中编写这些字符,但这到底意味着什么? 哪些功能可以使Spring Boot具有如此强大的功能并使Spring应用程序开发如此容易&#…

java 使用本机代理_Java与本机代理–他们所做的强大功能

java 使用本机代理在安装代理之前应了解的内容及其对代码的影响 在构建可伸缩的服务器端应用程序时,我们花费大量时间思考如何在生产中监视,操作和更新代码。 已经开发出一种新的工具来帮助Java和Scala开发人员做到这一点。 它们中的许多都是建立在最强大…

在任何无法理解的情况下,请编写脚本

脚本编写是使您的应用程序在运行时就可以根据客户需求进行调整的最流行的方法之一。 与往常一样,此方法不仅带来好处,例如,在灵活性和可管理性之间存在众所周知的折衷方案。 本文不是从理论上讨论优缺点的文章之一,而是从实践上展…

下载anaconda时出现“Please make sure you are connected to the internet”警告

如题,在anaconda下载过程中下载VScode时出现下图的警告。 百度翻译: 顺着图中指定文件路径,找到vscode_inst.py.log文件(注:有些人ProgramData文件夹可能找不到,打开任意文件夹,点击查看&…

多个公证员提高网络吞吐量

您是否需要非常高吞吐量的Corda网络? 网络的吞吐量是否稳定? 您是否已经从其他领域挤出了所有可能的表现? 如果您对这些问题的回答是“是”,那么我可能会为您提供一些有用的信息。 我列出了这些问题,以减少您过早优化C…

初识FPGA(搬运)

原文链接1原文链接2 fpga简介 FPGA(Field-Programmable Gate Array), 即现场可编程门阵列,它是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑器件)、CPL(复杂可…

蓝桥杯小白系列之汇编点亮led灯

蓝桥杯小白系列之汇编点亮led灯 1、源代码 2、逐条分析 (1)ORG 0000H (2)START: 伪指令,编译器可识别,单片机不可识别,可以随便起。 (3)蜂鸣器设置 蓝桥板插电以后蜂鸣器常会自动响起,故在程序前提前加上如下代码,让蜂鸣器不响: mov P2,#0A0H mov P0,#000H 参照…

带有Oracle Digital Assistant和Fn Project的会话式UI。 第二部分

在上一篇文章中,我使用Oracle Digital Assistant为FlexDeploy实现了一个对话式UI。 今天,我将用Fn Flow丰富它,以便聊天机器人接受发行名称而不是ID来创建快照。 完成后,对话听起来会更加自然: … “您可以建立快照吗…

小白系列之51单片机的入门速成法

51单片机的入门速成法 01-经典51内核资源全览浓缩图 02-重要外设特殊功能寄存器概览 03-程序开发流程与设计要点 04-三大外设的开发与可重用代码 05-应用程序设计入门一例通 01-经典51内核资源全览浓缩图 <1> 四组8位并行I/O端口&#xff1a; P0端口&#xff1a;PC门&a…