代表性状态转移(REST)是一种Web开发体系结构设计风格,它指的是逻辑上分离您的API资源,以便能够轻松访问,操纵和扩展。 可重用组件的编写方式使它们可以通过简单直观的HTTP请求轻松进行管理,这些HTTP请求可以是GET,POST,PUT,PATCH和DELETE(可以有更多,但以上是最常用的组件)。
尽管看起来很像,REST却没有命令协议或标准。 它只是设置了用于编写Web应用程序和API的软件体系结构样式,并简化了应用程序内部和外部的接口。 编写的遵循REST原则的Web服务API被称为RESTful API。
在这个由三部分组成的教程系列中,我将介绍使用Flask作为Web框架创建RESTful API的不同方法。 在第一部分中,我将介绍如何创建基于类的REST API,这些API更类似于DIY(自己动手做),即,自己实现它们而不使用任何第三方扩展。 在本系列的后半部分,我将介绍如何利用各种Flask扩展以更简单的方式构建更有效的REST API。
我假设您对使用Flask和环境设置最佳实践有基本的了解,并在开发Python应用程序时遵循使用virtualenv 。
安装依赖项
需要为我们将要开发的应用程序安装以下软件包。
$ pip install flask
$ pip install flask-sqlalchemy
上面的命令应安装此应用程序运行所需的所有必需软件包。
烧瓶应用
对于本教程,我将创建一个小型应用程序,在其中为Product
创建一个简单的模型。 然后,我将演示如何为它编写RESTful API。 下面是应用程序的结构。
flask_app/
my_app/
- __init__.py
product/
- __init__.py // Empty file
- models.py
- views.py
- run.py
我不会为此应用程序创建前端,因为可以通过使用各种其他方法进行HTTP调用来直接测试RESTful API端点。
flask_app / my_app / __ init__.py
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:tmp/test.db'
db = SQLAlchemy(app)
from my_app.catalog.views import catalog
app.register_blueprint(catalog)
db.create_all()
在上面的文件中,已使用扩展名的初始化并最终创建数据库来配置应用程序。 如果该位置还不存在数据库,则最后一条语句将在针对SQLALCHEMY_DATABASE_URI
提供的位置处创建一个新数据库,否则它将使用同一数据库加载应用程序。
flask_app / my_app / catalog / models.py
from my_app import db
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
price = db.Column(db.Float(asdecimal=True))
def __init__(self, name, price):
self.name = name
self.price = price
def __repr__(self):
return '<Product %d>' % self.id
在上面的文件中,我创建了一个非常简单的模型来存储Product
的名称和价格。 这将在SQLite
创建一个与模型中提供的详细信息相对应的表。
flask_app / my_app / catalog / views.py
import json
from flask import request, jsonify, Blueprint, abort
from flask.views import MethodView
from my_app import db, app
from my_app.catalog.models import Product
catalog = Blueprint('catalog', __name__)
@catalog.route('/')
@catalog.route('/home')
def home():
return "Welcome to the Catalog Home."
class ProductView(MethodView):
def get(self, id=None, page=1):
if not id:
products = Product.query.paginate(page, 10).items
res = {}
for product in products:
res[product.id] = {
'name': product.name,
'price': str(product.price),
}
else:
product = Product.query.filter_by(id=id).first()
if not product:
abort(404)
res = {
'name': product.name,
'price': str(product.price),
}
return jsonify(res)
def post(self):
name = request.form.get('name')
price = request.form.get('price')
product = Product(name, price)
db.session.add(product)
db.session.commit()
return jsonify({product.id: {
'name': product.name,
'price': str(product.price),
}})
def put(self, id):
# Update the record for the provided id
# with the details provided.
return
def delete(self, id):
# Delete the record for the provided id.
return
product_view = ProductView.as_view('product_view')
app.add_url_rule(
'/product/', view_func=product_view, methods=['GET', 'POST']
)
app.add_url_rule(
'/product/<int:id>', view_func=product_view, methods=['GET']
)
上面的文件中处理了本教程的主要问题。 Flask提供了一个称为可插入视图的实用程序,该实用程序允许您以类的形式(而不是通常以函数的形式)创建视图。 基于方法的调度( MethodView
)是可插入视图的实现,它使您可以使用小写形式编写与HTTP方法相对应的方法。 在上面的示例中,我编写了分别对应于HTTP的GET
和POST
方法get()
和post()
。
在上述文件的最后几行中,路由也以不同的方式实现。 我们可以指定任何特定规则将支持的方法。 Error 405 Method not allowed
将导致任何其他HTTP调用。
运行应用程序
要运行该应用程序,请执行脚本run.py
该脚本的内容是:
from my_app import app
app.run(debug=True)
现在只需从命令行执行:
$ python run.py
要检查该应用程序是否正常运行,请在浏览器中启动http://127.0.0.1:5000/ ,然后会出现一个带有欢迎消息的简单屏幕。
测试RESTful API
为了测试此API,我们可以简单地使用许多可用方法中的任何一种进行HTTP调用。 GET调用可以直接通过浏览器进行。 可以使用Chrome扩展程序(如Postman)或通过使用curl
的命令行来进行POST调用,或者我们可以使用Python的requests
库为我们完成这项工作。 我将在此处使用请求库进行演示。
让我们先进行GET
调用,以确保我们尚未创建任何产品。 根据RESTful API的设计,类似于/product/
的get调用应列出所有产品。 然后,我将使用一些数据对/product/
进行POST
调用来创建几个产品。 然后,对/product/
的GET
调用应列出所有创建的产品。 要获取特定产品,应该对/product/<product id>
进行GET
调用。 以下是使用此示例可以进行的所有调用的示例。
$ pip install requests
$ python
>>> import requests
>>> r = requests.get('http://localhost:5000/product/')
>>> r.json()
{}
>>> r = requests.post('http://localhost:5000/product/', data={'name': 'iPhone 6s', 'price': 699})
>>> r.json()
{u'1': {u'price': u'699.0000000000', u'name': u'iPhone 6s'}}
>>> r = requests.post('http://localhost:5000/product/', data={'name': 'iPad Pro', 'price': 999})
>>> r.json()
{u'2': {u'price': u'999.0000000000', u'name': u'iPad Pro'}}
>>> r = requests.get('http://localhost:5000/product/')
>>> r.json()
{u'1': {u'price': u'699.0000000000', u'name': u'iPhone 6s'}, u'2': {u'price': u'999.0000000000', u'name': u'iPad Pro'}}
>>> r = requests.get('http://localhost:5000/product/1')
>>> r.json()
{u'price': u'699.0000000000', u'name': u'iPhone 6s'}
结论
在本教程中,您了解了如何使用Flask的可插入视图实用程序自行创建RESTful接口。 这是编写REST API时最灵活的方法,但是要编写的代码要多得多。
有一些扩展使生活变得更轻松,并在很大程度上自动化了RESTful API的实现。 我将在本教程系列的下两部分中介绍这些内容。
翻译自: https://code.tutsplus.com/tutorials/building-restful-apis-with-flask-diy--cms-26625