8-----ret简介以及flask实现restfule api

什么是 REST?

六条设计规范定义了一个 REST 系统的特点:
客户端-服务器: 客户端和服务器之间隔离,服务器提供服务,客户端进行消费。
无状态: 从客户端到服务器的每个请求都必须包含理解请求所必需的信息。换句话说, 服务器不会存储客户端上一次请求的信息用来给下一次使用。
可缓存: 服务器必须明示客户端请求能否缓存。
分层系统: 客户端和服务器之间的通信应该以一种标准的方式,就是中间层代替服务器做出响应的时候,客户端不需要做任何变动。
统一的接口: 服务器和客户端的通信方法必须是统一的。
按需编码: 服务器可以提供可执行代码或脚本,为客户端在它们的环境中执行。这个约束是唯一一个是可选的。

什么是一个 RESTful 的 web service?
REST 架构的最初目的是适应万维网的 HTTP 协议。
RESTful web services 概念的核心就是“资源”。 资源可以用 URI 来表示。客户端使用 HTTP 协议定义的方法来发送请求到这些 URIs,当然可能会导致这些被访问的”资源“状态的改变。

如下示例格式:

==========  ===============================================  =============================
HTTP 方法   URL                                              动作
==========  ===============================================  ==============================
GET         http://[hostname]/devops/api/v1.0/tasks            检索任务列表
GET         http://[hostname]/devops/api/v1.0/tasks/[task_id]  检索某个任务
POST        http://[hostname]/devops/api/v1.0/tasks            创建新任务
PUT         http://[hostname]/devops/api/v1.0/tasks/[task_id]  更新任务
DELETE      http://[hostname]/devops/api/v1.0/tasks/[task_id]  删除任务

##我们定义的任务有如下一些属性:

id: 任务的唯一标识符。数字类型。
title: 简短的任务描述。字符串类型。
description: 具体的任务描述。文本类型。
done: 任务完成的状态。布尔值。
目前为止关于我们的 web service 的设计基本完成。剩下的事情就是实现它!

第一个示例Get请求:
[root@localhost opt]# cat test.py 
from flask import Flask, jsonify

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})

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

####
[root@localhost ~]# curl -i http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 317
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:12:40 GMT

{
  "tasks": [
    {
      "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
      "done": false, 
      "id": 1, 
      "title": "Buy groceries"
    }, 
    {
      "description": "Need to find a good Python tutorial on the web", 
      "done": false, 
      "id": 2, 
      "title": "Learn Python"
    }
  ]
}
##返回json格式的结果。

2、接下来函数该子,当传入id 的时候,返回对应id 的结果:

[root@localhost opt]# cat test.py 
from flask import Flask, jsonify, 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'])
@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id=None):
    if task_id:
        task = [i for i in tasks if i['id']==task_id]
        print(task)
        if len(task) == 0:
            abort(404)
        return jsonify({'task': task})
    else:
        return jsonify({'tasks': tasks})

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

##测试结果:
[root@localhost opt]# curl -i http://localhost:5000/todo/api/v1.0/tasks/3
HTTP/1.0 404 NOT FOUND
Content-Type: text/html
Content-Length: 232
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:30:56 GMT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
[root@localhost opt]# curl -i http://localhost:5000/todo/api/v1.0/tasks/1
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 162
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:31:00 GMT

{
  "task": [
    {
      "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
      "done": false, 
      "id": 1, 
      "title": "Buy groceries"
    }
  ]
}
[root@localhost opt]# curl -i http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 317
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:31:02 GMT

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

*当资源不存在的时候,返回404,但是这种返回效果不太好,为了优雅的线上,我们添加一个装饰器:

from flask import make_response

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

###测试一下结构查询结果:
[root@localhost opt]# curl -i http://localhost:5000/todo/api/v1.0/tasks/3
HTTP/1.0 404 NOT FOUND
Content-Type: application/json
Content-Length: 27
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:35:14 GMT

{
  "error": "Not found"
}

4、添加post请求:

from flask import request

@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    if not request.json or not 'title' in request.json:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

##先做判断没有收到json数据,或者没有title就返回400,并且返回201状态码

[root@localhost opt]# curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 201 CREATED
Content-Type: application/json
Content-Length: 105
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:38:52 GMT

{
  "task": {
    "description": "", 
    "done": false, 
    "id": 3, 
    "title": "Read a book"
  }
}

##添加两条数据发现数据已经添加到了内存:
[root@localhost opt]# curl -i http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 531
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:41:14 GMT

{
  "tasks": [
    {
      "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
      "done": false, 
      "id": 1, 
      "title": "Buy groceries"
    }, 
    {
      "description": "Need to find a good Python tutorial on the web", 
      "done": false, 
      "id": 2, 
      "title": "Learn Python"
    }, 
    {
      "description": "", 
      "done": false, 
      "id": 3, 
      "title": "Read a book"
    }, 
    {
      "description": "", 
      "done": false, 
      "id": 4, 
      "title": "Read a book"
    }
  ]
}


##剩余的PUT和DELETE方法:

@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['PUT'])
def update_task(task_id):
    task = [i for i in tasks if i['id']==task_id]
    print(task)
    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})

@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
    task = [i for i in tasks if i['id']==task_id]
    if len(task) == 0:
        abort(404)
    tasks.remove(task[0])
    print(tasks)
    return jsonify({'result': True})

##测试验证,更新一下2的状态:

[root@localhost opt]#  curl -i -H "Content-Type: application/json" -X PUT -d '{"done":true}' http://localhost:5000/todo/api/v1.0/tasks/2
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 171
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:54:17 GMT

{
  "task": [
    {
      "description": "Need to find a good Python tutorial on the web", 
      "done": true, 
      "id": 2, 
      "title": "Learn Python"
    }
  ]
}

##删除task_2:

[root@localhost opt]# curl -i -X DELETE http://localhost:5000/todo/api/v1.0/tasks/2
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 21
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:58:31 GMT

{
  "result": true
}
[root@localhost opt]# curl -i -X GET http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 163
Server: Werkzeug/0.15.6 Python/3.6.4
Date: Tue, 15 Oct 2019 15:58:49 GMT

{
  "tasks": [
    {
      "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
      "done": false, 
      "id": 1, 
      "title": "Buy groceries"
    }
  ]
}

 

posted @ 2020-04-06 15:57  王竹笙  阅读(333)  评论(0编辑  收藏  举报