RESTful是一种API设计规范。
在RESTful架构中,主要使用POST,DELETE,PUT和GET四种HTTP请求方式分别对指定的URL资源进行增删改查操作。
RESTful之前的做法:
/users/query/1 GET 根据用户id查询用户数据
/users/save POST 新增用户
/users/update POST 修改用户信息
/users/delete GET/POST 删除用户信息
RESTful做法:
/users/1 GET 根据用户id查询用户数据
/users POST 新增用户
/users PUT 修改用户信息
/users DELETE 删除用户信息
客户端的每一次请求,服务器都会给出回应,回应包括 HTTP 状态码和数据两部分。
部分状态码:
GET: 200 OK
POST: 201 Created
PUT: 200 OK
DELETE: 204 No Content
使用Flask实现一个RESTful API服务的例子
from flask import Flask,jsonify,abort,make_response,request
from flask_httpauth import HTTPBasicAuth
app = Flask(__name__)
auth = HTTPBasicAuth()
users = [
{
'id': 1,
'username': '小明',
'sex': 1
},
{
'id': 2,
'username': '小红',
'sex': 0
}
]
#访问前需要提供用户名和密码
@auth.get_password
def get_password(username):
if username == 'admin':
return '123456'
return None
#友好的错误提示:没有权限
@auth.error_handler
def unauthorized():
return make_response(jsonify({'error': '未授权'}), 403)
#友好的错误提示:找不到资源页面
@app.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error': '找不到资源'}), 404)
#返回所有用户的记录
@app.route('/api/v1.0/users', methods=['GET'])
@auth.login_required #需要认证
def get_users():
return jsonify({'users': users})
#返回一个用户的记录记录
@app.route('/api/v1.0/users/<int:user_id>', methods=['GET'])
@auth.login_required
def get_user(user_id):
user = list(u for u in users if u['id'] == user_id)
if len(user) == 0:
abort(404)
return jsonify({'user': user[0]})
#插入一条用户记录
@app.route('/api/v1.0/users', methods=['POST'])
@auth.login_required
def create_user():
if not request.json or not 'username' in request.json or not 'sex' in request.json:
abort(400)
user = {
'id': users[-1]['id'] + 1,
'username': request.json['username'],
'sex': request.json['sex']
}
users.append(user)
return jsonify({'user': user}), 201
#更新一个用户的记录
@app.route('/api/v1.0/users/<int:user_id>', methods=['PUT'])
@auth.login_required
def update_user(user_id):
user = list(u for u in users if u['id'] == user_id)
if len(user) == 0:
abort(404)
if not request.json:
abort(400)
user[0]['username'] = request.json.get('username', user[0]['username'])
user[0]['sex'] = request.json.get('sex', user[0]['sex'])
return jsonify({'user': user[0]})
#删除一个用户的记录
@app.route('/api/v1.0/users/<int:user_id>', methods=['DELETE'])
@auth.login_required
def delete_user(user_id):
user = list(u for u in users if u['id'] == user_id)
if len(user) == 0:
abort(404)
users.remove(user[0])
return jsonify({'result': True}),204
if __name__ == '__main__':
app.run(debug=True)
上面例子,也可以使用Flask-RESTful实现
from flask import Flask,jsonify,abort,make_response,request
from flask_httpauth import HTTPBasicAuth
from flask_restful import Api,Resource,reqparse
app = Flask(__name__)
api = Api(app)
auth = HTTPBasicAuth()
users = [
{
'id': 1,
'username': '小明',
'sex': 1
},
{
'id': 2,
'username': '小红',
'sex': 0
}
]
#验证字段的合法性
parser = reqparse.RequestParser()
parser.add_argument('username', type = str, required = True, help = '此字段格式有问题', location = 'json')
parser.add_argument('sex', type = int, default = "1", location = 'json')
#访问前需要提供用户名和密码
@auth.get_password
def get_password(username):
if username == 'admin':
return '123456'
return None
class UserListAPI(Resource):
decorators = [auth.login_required]
def get(self):
return {'users': users}
def post(self):
args = parser.parse_args()
user = {
'id': users[-1]['id'] + 1,
'username': args['username'],
'sex': args['sex']
}
users.append(user)
return {'user': user}, 201
class UserAPI(Resource):
decorators = [auth.login_required]
def get(self, id):
user = list(u for u in users if u['id'] == id)
if len(user) == 0:
abort(404)
return {'user': user[0]}
def put(self, id):
user = list(u for u in users if u['id'] == id)
if len(user) == 0:
abort(404)
user = user[0]
args = parser.parse_args()
for k, v in args.items():
if v != None:
user[k] = v
return { 'user': user }
def delete(self, id):
user = list(u for u in users if u['id'] == id)
if len(user) == 0:
abort(404)
users.remove(user[0])
return {'result': True}
api.add_resource(UserListAPI, '/api/v1.0/users', endpoint = 'users')
api.add_resource(UserAPI, '/api/v1.0/users/<int:id>', endpoint = 'user')
if __name__ == '__main__':
app.run(debug=True)
使用Postman测试接口
创建一个新的Request,Request name和Create Collection都随便输入如RESTfulAPI,保存后,自动打开名称为RESTfulAPI的标签页。
(1)测试/api/v1.0/users的GET请求
RESTfulAPI标签页默认选择 GET,输入:localhost:5000/api/v1.0/users,这里直接点击Send按钮,Postman返回码:Status:403 FORBIDDEN,返回内容
{
"error": "未授权"
}
在Authorization标签里面TYPE选择Basic Auth,右边Username和Password分别输入admin和123456。

点击Send按钮,Postman返回码:Status:201 CREATED,返回内容:
{
"users": [
{
"id": 1,
"sex": 1,
"username": "小明"
},
{
"id": 2,
"sex": 0,
"username": "小红"
}
]
}
(2)测试/api/v1.0/users/<int:user_id>的GET请求
修改Postman的请求方法和地址为:GET localhost:5000/api/v1.0/users/2
(3)测试/api/v1.0/users的POST请求
修改Postman的请求方法和地址为:POST localhost:5000/api/v1.0/users
在Body标签里面选择raw、修改最后的默认Text为JSON(application/json),下面输入框填写:
{
"id": 3,
"sex": 1,
"username": "小强"
}
点击Send按钮,Postman返回码:Status:201 CREATED
把POST方法直接改为GET方法,可见返回3条记录。
(4)测试/api/v1.0/users/<int:user_id>的PUT请求
修改Postman的请求方法和地址为:PUT localhost:5000/api/v1.0/users/3
在Body标签里面选择raw、修改最后的默认Text为JSON(application/json),下面输入框填写:
{
"id": 3,
"sex": 1,
"username": "小刚"
}
点击Send按钮,Postman返回码:Status:200 OK
(5)测试/api/v1.0/users/<int:user_id>的DELETE请求
修改Postman的请求方法和地址为:DELETE localhost:5000/api/v1.0/users/3
点击Send按钮,Postman返回码:Status:204 NOT CONTENT
使用Python的第三方库requests测试接口
import requests,json
url = 'http://localhost:5000/api/v1.0'
auth = ('admin','123456')
#查询
r=requests.get(url + '/users', auth=auth)
print(r.status_code, r.text)
#在控制台输出时中文会用unicode显示,可用下面方法显示中文
#print(json.dumps(json.loads(r.text),ensure_ascii=False))
r=requests.get(url + '/users/1', auth=auth)
print(r.status_code, r.text)
#更新
data = {
"id": 3,
"sex": 1,
"username": "小强"
}
r=requests.post(url + '/users', auth=auth, json=data)
print(r.status_code, r.text)
#修改
data = {
"id": 3,
"sex": 1,
"username": "小刚"
}
r=requests.put(url + '/users/3', auth=auth, json=data)
print(r.status_code, r.text)
#删除
r=requests.delete(url + '/users/3', auth=auth)
print(r.status_code, r.text)
本文介绍了如何使用Python的Flask框架实现RESTful API,并利用Postman工具进行接口测试。详细展示了GET、POST、PUT、DELETE四种HTTP请求方式在Flask中的应用,以及在Postman中如何配置请求参数,获取不同状态码和响应内容。
656

被折叠的 条评论
为什么被折叠?



