创建 Python API
REST 是现代领域 Web API 的一个极其强大的解决方案。它提供了广泛的优势,可以帮助任何服务变得更高效、更快迭代、更稳定。
Python 是一种强大的高级语言,可以在广泛的系统和设备类别中解锁高级功能。它是人类可读的、高效的并且被广泛采用。
这两种技术结合起来,可以在 API 领域提供令人难以置信的产品。在本指南中,我们将讨论什么是 REST、如何打造真正的 RESTful 以及 Python 如何支持这项工作。我们将研究一些最佳实践。
什么是REST?
REST(即表述性状态传输)是系统通信的范例。这一概念是让系统通过一种无状态模式相互通信,这种模式利用资源状态的表示而不是资源本身。本质上,每次交互都是利用资源请求者和资源持有者之间的特定关系进行有状态表示,这允许跨各种用例进行无缝交互。
REST基础知识
REST 作为一个概念首次在Roy Fielding 的一篇现已著名的论文中被分享。在这篇论文中,菲尔丁定义了一种基于表征状态转移的新通信方式。虽然在实践中有多种可选属性可以使某些东西变得“RESTful”,但 REST 的核心本质最好定义如下:
- REST 利用“客户端-服务器关系”。这意味着客户端和服务器有自己的域和状态,并且服务器与客户端交互(反之亦然)以提供功能。换句话说,在 REST 中,只有一种通信方式——“客户端向服务器发出请求,服务器响应客户端”。
- REST 是“无状态”的。 “状态”是给定资源的当前属性和性质。在无状态环境中,状态完全在客户端进行管理,对服务器的请求应包含处理和返回响应所需的所有信息。本质上,“REST 利用无状态性使每个请求都是独立的”。
- REST 有一个“统一的接口”。每个组件都有一个预定义且一致的接口,这意味着与组件的交互“必须使用相同的模式和构造”,而不管服务内的形式或功能如何。资源必须有一个单一的 URI,并且应该在可能的情况下引用额外的数据或信息——这就是 HATEOAS/超媒体,并且是 RESTful 的一个主要部分。
- REST 必须是“可缓存的”。在 REST 中,服务器将数据标记为可以缓存或无法缓存的数据,这对性能、服务器需求和用户体验有重大影响。 ”’REST 必须支持缓存选择”’。应可缓存的数据必须可缓存,并且必须如此声明。
- REST 是分层的。 RESTful 组件允许分布式架构,客户端通常不知道它是直接连接到服务器还是架构中的微服务和中间件系统之一。
什么是Python?
充分了解 REST 后,我们来看看 Python。 Python 是一种编程语言,于 1991 年首次发布,作为 ABC 的后继语言。该语言的目的是人类可读且高效,重点是垃圾收集、动态类型和多范式支持。它将各种库打包在一起,以实现大量的功能和用途,因此,它是 Web API 的一个非常受欢迎的选择。
Python 很受欢迎,因为它很容易上手。它使用简单的语法,具有很高的可读性,利用正常的人类语音和空格使事情变得更清晰、更容易理解。它将许多复杂的底层功能抽象为简单的结构,使您能够以低摩擦快速上手。
值得注意的是,Python 在各种系统和环境中具有高度的跨平台支持。该社区异常强大,这意味着在那些没有本机 Python 支持的环境中,可能存在允许此功能和集成的社区扩展或系统。
如何使用 Python 创建 RESTful API
出于本文的目的,我们将使用 Python 和 Flask。有多种优秀的 Python API 开发工具,但我们使用 Flask,因为它不需要任何工具或库即可开始构建 Web API。 Flask 确实有扩展来添加额外的功能,但对于这个 API,我们将直接使用开箱即用的工具集。
设置您的开发环境
首先,本教程假设您已经安装了 Python。如果不这样做,请导航到 Python 网页并通过适合您的环境“可缓存”的方法进行安装。
安装烧瓶
安装Python后,必须先安装Flask。为此,请发出以下命令:
pip install flask
这将从 Python 包索引安装 Flask。
创造环境
接下来,您需要为 Python API 创建一个目录。我们将此目录称为“Moesif_tutorial:
mkdir moesif_tutorial && cd moesif_tutorial
此代码将创建目录 (mkdir) 并将工作目录 (cd) 更改为新创建的位置。从这里,您需要创建新的项目文件。我们将其称为“tutorial_app”。
touch tutorial_app.py
通过“触摸”该文件,我们正在创建构建文件并准备好保存我们的项目。 “touch”将创建该文件,但我们需要启动一个虚拟环境来处理它。为此,请使用以下命令:
python3 -m venv <venv>/bin/activate
此命令将取决于您的环境目录 – 有关如何正确启动此目录的更多信息,请参阅Python 文档。
创建 API 骨架
创建环境后,我们将制作 API。这个 API 非常简单 – 它将包含有关三个 Python 框架的详细信息,并允许用户检索有关这些框架的信息。
要开始构建 API,我们将直接编辑tutorial_app.py。在该文件中,添加以下代码:
from flask import Flask
app = Flask(__name__)
它的作用是实例化 Flask 类,实际上是“创建”应用程序。有了这个,我们接下来创建了一个具有名称值的类实例,我们将在其中将 Flask 指向各种文件和元素。
这是 Python 应用程序的最基本版本 – 但为了使其成为 RESTful 版本,我们需要查询端点,在我们的例子中,这意味着我们需要一些数据供其引用。由于我们没有连接数据库,因此我们可以直接将此数据存储为数据存储。在Python中,数据存储是我们可以存储在应用程序本身中的一段任意代码,这使我们能够在没有数据库或外部数据存储解决方案的情况下托管数据。
为此,我们可以将数据存储附加到我们的文件中:
from flask import Flask
app = Flask(__name__)
in_memory_datastore = {
"Flask" : {"name": "Flask", "created": 2010, "parent": "Python"},
"Django" : {"name": "Django", "created": 2005, "parent": "Python"},
"Bottle" : {"name": "Bottle", "created": 2009, "parent": "Python"},
"Tornado" : {"name": "Tornado", "created": 2010, "parent": "Python"},
}
创建端点
现在您已经有了 API 的骨架——它有一个实例化的应用程序和一个资源。接下来,我们需要创建可以查询的端点。为此,我们将使用 HTTP 动词 GET 从tutorial_app.py 检索数据:
@app.get('/frameworks')
def list_frameworks():
return {"frameworks":list(in_memory_datastore.values())}
这里有几件事要提一下。首先,“/frameworks”区域定义了我们的端点。使用 GET HTTP 谓词向该端点发出的请求将触发此功能。对于其他端点,您只需更改此名称并生成新端点即可。其次,@app.get 是另一种方法的简写。一些 Python 开发人员可能更熟悉“@app.route”——在这种情况下,app.get 和 app.route 是同一个,只是构建略有不同。
我们的方法如下所示:
@app.get('/frameworks')
另一种写法如下:
@app.route('/frameworks', methods=["GET"])
请注意,这两段代码执行相同的操作 – 我们的版本只是更短。回到代码中所写的:
@app.get('/frameworks')
def list_frameworks():
return {"frameworks":list(in_memory_datastore.values())}
代码的其余部分定义了一个带有“frameworks”标签的 JSON 对象,并将其指向我们数据存储中的值。这将允许我们访问 /frameworks 端点并查看所有资源的列表。为此,您可以导航至:
http://127.0.0.1:5000/frameworks
实现CRUD功能
到目前为止,我们已经有了一个 API,可以让我们检索数据列表。我们需要做的是开始添加额外的 CRUD 功能。例如,我们可以利用 PUT 创建一个更新函数。为此,我们可以更新代码以添加 POST 动词,从而在数据存储中创建新条目。首先,我们需要创建创建函数:
def create_framework(new_framework):
framework_name = new_framework['name']
in_memory_datastore[framework_name] = new_framework
return new_framework
这定义了一种将框架输入系统的新方法。接下来,我们需要添加一个路由方法来支持 CLI 命令与端点交互:
@app.route('/frameworks'’, methods=['GET', 'POST'])
def frameworks_route():
if request.method == 'GET':
return list_frameworks()
elif request.method == "POST":
return create_framework(request.get_json(force=True))
可以对 CRUD 功能所需的所有路由重复此操作。
让它变得宁静
现在您已经有了提供基本功能的 API 服务,您将需要开始添加一些系统以真正使其成为 RESTful。第一步是利用有效的 HATEOAS 上下文系统。
目前市场上有多种选择。 JSON-LD是一个很好的解决方案,它允许您提供链接数据作为资源的一部分。
在我们的实例中,这可能是这样的:
{
"@context": "https://example.com/frameworks.jsonld",
"@id": "https://example.com/frameworks/Flask",
"relatedName": "Flask-RESTPlus",
"relatedDocs": "https://flask-restplus.readthedocs.io/",
}
这也是您可能需要开始考虑用于缓存、优化等的额外框架的一点。一旦您拥有了一个稳定的 API 可供使用,您就可以开始添加额外的安全和稳定的功能,使您的应用程序真正实现 RESTful。
最佳实践
认证与授权
确保您使用基于最小权限原则的身份验证和授权来部署服务。尽可能锁定对资源的访问。确保你的上下文参考是有效的,并且它们是值得的——超媒体很棒,但暴露任何东西并不是对一个更加封闭、非上下文世界的正确反应。确保您提供的有用数据不会被用来对付您,并确保以安全的方式提供数据。
API结构
请记住,RESTful API 主要是面向资源的。资源应该有一个具有特定功能的HTTP 动词,并且应该是幂等的(例如,每次调用时响应的类型都是相同的,即使内容不同)。确保您充分链接到上下文信息并向客户端提供缓存。确保您与本文开头的 REST 考虑因素保持一致。
结论
RESTful 设计并不难做,但往往很难做得正确。通过一些前瞻性的思考和规划,您可以使用 Python 启动极其强大的 RESTful API。即使只是这篇文章中的代码也可以成为下一个大型 API 的核心——它只需要一些想象力和规划。
原文链接:https://www.moesif.com/blog/api-monetization/api-strategy/Creating-Python-APIs/