在本文中,我们将学习使用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体系结构:

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

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

步骤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

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

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

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

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

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

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

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

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

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

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

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

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

调用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对象提供。 以下屏幕截图描述了这一点:

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

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

将返回以下JSON:

使用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函数:

要对其进行测试,请使用下面的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响应:

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

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

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

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

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

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

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

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

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

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

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

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

使用AWS Lambda在Go中构建RESTful API相关推荐

  1. dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3(十)之Spring MVC中使用 Swagger2 构建Restful API...

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/55047193 1.Swagger2是什么? ...

  2. Spring MVC中使用 Swagger2 构建Restful API

    0.Spring MVC配置文件中的配置 [java] view plain copy <!-- 设置使用注解的类所在的jar包,只加载controller类 --> <span s ...

  3. 用 Flask 来写个轻博客 (33) — 使用 Flask-RESTful 来构建 RESTful API 之二

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 构建 RESTful Flask API 定义资源路由 格式 ...

  4. 用 Flask 来写个轻博客 (35) — 使用 Flask-RESTful 来构建 RESTful API 之四

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 POST 请求 身份认证 测试 前文列表 用 Flask 来写个轻博客 ...

  5. 用 Flask 来写个轻博客 (34) — 使用 Flask-RESTful 来构建 RESTful API 之三

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 应用请求中的参数实现 API 分页 测试 前文列表 用 Flask 来 ...

  6. springboot集成swagger2构建RESTful API文档

    在开发过程中,有时候我们需要不停的测试接口,自测,或者交由测试测试接口,我们需要构建一个文档,都是单独写,太麻烦了,现在使用springboot集成swagger2来构建RESTful API文档,可 ...

  7. asp编程工具_使用ASP.NET Core构建RESTful API的技术指南

    译者荐语:利用周末的时间,本人拜读了长沙.NET技术社区翻译的技术文章<微软RESTFul API指南>,打算按照步骤写一个完整的教程,后来无意中看到了这篇文章,与我要写的主题有不少相似之 ...

  8. 在C#中使用RESTful API的几种好方法

    在C#中使用RESTful API的几种好方法 原文来自互联网,由长沙DotNET技术社区编译. 通过Web开发的路径,您发现自己迟早需要处理外部API(应用程序编程接口).在本文中,我的目标是列出在 ...

  9. 使用ASP.NET Core 3.x 构建 RESTful API - 2. 什么是RESTful API

    1. 使用ASP.NET Core 3.x 构建 RESTful API - 1.准备工作 什么是REST REST一词最早是在2000年,由Roy Fielding在他的博士论文<Archit ...

最新文章

  1. 深入理解 Linux Cgroup 系列(二):玩转 CPU
  2. 怎样远程连接服务器后上传文件,远程登录服务器后怎样上传文件
  3. 学习记录-Linux图形栈:基于DRM和Wayland
  4. html一行省略号变手型,鼠标移动到表格的TD上的时候显示成一个手型的样子怎么做?...
  5. Egret资源管理解决方案
  6. 南蛮图腾(洛谷P1498题题解,Java语言描述)
  7. hdu 2037(今年暑假不AC)
  8. linux脚本调用job,linux shell - 脚本中调用fg调取后台任务报错
  9. mysql join 条件_MySQL Join 竟然可以这么玩?根据条件 进行复制
  10. android 判断资源是否使用6,android-download-manager – Android 6获取下载文件的路径
  11. cocos2d-iphone 区分ipad和iphone
  12. 从神话诗歌到奇幻科学的人类探索史·《月亮》·三
  13. 电阻电容等封装对应功率
  14. 虚拟机访问服务器文件夹,浅析CentOS8虚拟机访问Windows10主机文件夹方法
  15. win7如何关闭uac
  16. 2021年Java常见面试题,实战篇
  17. 融360叶大清:不关注短期股价变化 希望触达三四线城市年轻人
  18. LSD计算机控制人体大脑,科学家发现了LSD对大脑的影响
  19. 麻省理工学院:科技宠儿的摇篮
  20. 百度浏览器的编程html,百度来路浏览器劫持代码(替换浏览器正在浏览页面)...

热门文章

  1. 【贪心】Sunscreen(poj 3614/luogu 2887)
  2. 节操大师 北方大学生程序设计竞赛 南开大学
  3. JavaFX UI控件教程(二十二)之Titled Pane和Accordion
  4. MySQL max()函数
  5. C++描述杭电OJ 2014. 青年歌手大奖赛_评委会打分 ||
  6. 《给教师的阅读建议》经典语录
  7. 《金色梦乡》金句摘抄(五)
  8. sh(Spring+Spring mvc+hibernate)——IDeptDao.java
  9. 使用JDBCTemplate实现与Spring结合,方法公用 ——接口(BaseDao)
  10. win10控制视频声音大小