使用python的Flask实现一个简单RESTful API服务器端

找了一篇教程学习了一下,为了加深印象照着写了一遍存下来,原文链接如下:传送门

REST的六个特性

  • Client-Server:服务器端与客户端分离。
  • Stateless(无状态):每次客户端请求必需包含完整的信息,换句话说,每一次请求都是独立的。
  • Cacheable(可缓存):服务器端必需指定哪些请求是可以缓存的。
  • Layered System(分层结构):服务器端与客户端通讯必需标准化,服务器的变更并不会影响客户端。
  • Uniform Interface(统一接口):客户端与服务器端的通讯方法必需是统一的。
  • Code on demand(按需执行代码?):服务器端可以在上下文中执行代码或者脚本?

HTTP请求方法

  1. GET 请求指定的页面信息,并返回实体主体。
  2. HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
  3. POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
  4. PUT 从客户端向服务器传送的数据取代指定的文档的内容。
  5. DELETE 请求服务器删除指定的页面。
  6. CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
  7. OPTIONS 允许客户端查看服务器的性能。
  8. TRACE 回显服务器收到的请求,主要用于测试或诊断。

规划资源的URL

GET http://[hostname]/todo/api/v1.0/tasks 检索任务清单
GET http://[hostname]/todo/api/v1.0/tasks/[task_id] 检索一个任务
POST http://[hostname]/todo/api/v1.0/tasks 创建一个新任务
PUT http://[hostname]/todo/api/v1.0/tasks/[task_id] 更新一个已存在的任务
DELETE http://[hostname]/todo/api/v1.0/tasks/[task_id] 删除一个任务

我们定义任务清单有以下字段:
id:唯一标识。整型。
title:简短的任务描述。字符串型。
description:完整的任务描述。文本型。
done:任务完成状态。布尔值型。

代码实现以及注释

#!flask/bin/python
# -*- coding:UTF-8 -*-
from flask import Flask, jsonify
from flask import make_response
from flask import request
from flask import abort

app = Flask(__name__)

tasks = [
    {
        'id': 1,
        'title': u'Buy groceries',
        'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
        'done': False
    },
    {
        'id': 2,
        'title': u'Learn Python',
        'description': u'Need to find a good Python tutorial on the web',
        'done': False
    }
]


@app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})


#通过参数,检索tasks数组。如果参数传过来的id不存在于数组内,我们需要返回错误代码404
#按照HTTP的规定,404意味着是"Resource Not Found",资源未找到。
#如果找到任务在内存数组内,我们通过jsonify模块将字典打包成JSON格式
#并发送响应到客户端上。就像处理一个实体字典一样。
@app.route('/todo/api/v1.0/tasks/', methods=['GET'])
def get_task(task_id):
    task = filter(lambda t: t['id'] == task_id, tasks)
    if len(task) == 0:
        abort(404)
    return jsonify({'task':task[0]})

#使用post方法插入一个新的任务到数组中
@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    #request.jason里面包含请求数据,如果不是JSON或者里面没有包含title字段
    if not request.json or not 'title' in request.json:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1, #task[-1]代表原来的最后一位
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

#更改数据
@app.route('/todo/api/v1.0/tasks/', methods=['PUT'])
def update_task(task_id):
    task = filter(lambda t: t['id'] == task_id, tasks)
    if len(task) == 0:
        abort(404)
    if not request.json:
        abort(400)
    if 'title' in request.json and type(request.json['title']) != unicode:
        abort(400)
    if 'description' in request.json and type(request.json['description']) is not unicode:
        abort(400)
    if 'done' in request.json and type(request.json['done']) is not bool:
        abort(400)
    task[0]['title'] = request.json.get('title', task[0]['title'])
    task[0]['description'] = request.json.get('description', task[0]['description'])
    task[0]['done'] = request.json.get('done', task[0]['done'])
    return jsonify({'task': task[0]})

#删除数据
@app.route('/todo/api/v1.0/tasks/', methods=['DELETE'])
def delete_task(task_id):
    task = filter(lambda t: t['id'] == task_id, tasks)
    if len(task) == 0:
        abort(404)
    tasks.remove(task[0])
    return jsonify({'result': True})

if __name__ == '__main__':
    app.run(debug=True)

你可能感兴趣的:(python相关)