接口概念
IOP:面向接口编程,不再关注具体的实现;只关注输入、输出。
http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html
服务器返回数据类型:
网页数据html,为浏览器使用
Json数据,ajax javascript发请求的一种方式;也可以使用request的python请求方式
为移动端编写接口关注:
接口地址是什么:/xxx/yyy/zzz
接口需要什么参数:参数根据业务场景
返回什么格式的数据:大多数是json数据
RestfulAPI
一种软件架构风格、设计风格、而不是标准,只是提供了一组设计原则和约束条件。它主要用户客户端和服务器交互类的软件。
基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。REST全程是Representational State Transfer,表征性状态转移。
首次在2000年Roy Thomas Fielding的博士论文中出现,Fielding是一个非常重要的人,他是HTTP协议(1.0版和1.1版)的主要设计者,
Apache服务器软件的作者之一,Apache基金会的第一任主席。所以,他的这篇论文一经发表,就引起了广泛的关注。
理解RESTful
介绍:https://github.com/RockTeach/PythonCourse/blob/master/web/flask/restful.md
要理解RESTful架构,最好的就是去理解它的单词 Representational State Transfer 到底是什么意思,它的每一个词到底要表达什么。
REST的释义,"(资源的)表现层状态转化",其实这省略了主语。“表现层”其实指的是“资源(Resource)”的“表现层”。
状态码
服务器向用户返回的状态码和提示信息,常见的有以下一些地方
- 200:OK - [GET]:服务器成功返回用户请求的数据
- 201:CREATED -[POST/PUT/PATCH]:用户新建或修改数据成功
- 202:Accepted - [*] :表示一个请求已经进入后台排队(异步任务)
- 204:NO CONTENT - [DELETE]:表示数据删除成功
- 400:INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误
- 401:Unauthorized - [*] :表示用户没有权限(令牌,用户名,密码错误)
- 403:Forbidden - [*]:表示用户得到授权,但是访问是被禁止的
- 404:NOT FOUND - [*]:用户发出的请求针对的是不存在的记录
- 406:Not Acceptable - [*]:用户请求格式不可得
- 410:Gone - [GET] :用户请求的资源被永久移除,且不会再得到的
- 422:Unprocesable entity -[POST/PUT/PATCH]:当创建一个对象时,发生一个验证错误
- 500:INTERNAL SERVER EROR - [*] :服务器内部发生错误
所谓“资源”,就是网络上的一个实体,或者说是网络上的一个具体信息。
它可以是一段文本,一张图片,一首歌曲,一种服务,总之就是一个具体的实例。
你可以使用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。
要获取这个资源,访问它的URI就可以了,因此URI就成了每一个资源的地址或独一无二的识别符。所谓“上网”就是与互联网上一系列的“资源”互动,调用它们的URI。
“资源”是一种信息实体,它可以有多种外在表现形式。我们把“资源”具体呈现出来的形式,叫做它的”表现层“(Representation)。
URI只代表资源的实体,不代表它的形式。严格地说,有些网站最后的”.html“后缀名是不必要的,因为这个后缀表示格式,属于”表现层“范畴,而URI应该只代表”资源“的位置。
它的具体表现形式,应该在HTTP请求头的信息中使用Accept和Content-Type字段指定。
访问一个网站,就代表客户端和服务端的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。
互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务端。
因此,如果客户端想要操作服务器,就必须通过某种手段,让服务器端发生”状态转换(State Transfer)“。
而这种转换是建立在表现层之上的,所以就是”表现层状态转化“。
客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议中,四个表示操作方式的动词:GET,POST,PUT,DELETE。
它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可用于更新资源),PUT用来更新资源,DELETE用来删除资源
总结 :
- 每一个URI代表一种资源
- 客户端和服务器之间,传递这种资源的某种表现层
- 客户端通过四个HTTP动词,对服务端资源进行操作,实现”表现层状态转换“
- 同一个url针对用户的不同的请求操作,表现出来的状态是不同的。表现出来的多种形式,就是表现层状态转换。
-
CS,客户端和服务端这种架构模型中。
-
表现层状态转换
-
主语 (资源)
-
URI 每个URI代表一种资源
-
资源展现给我们的形式就叫做表现层
-
通过HTTP的请求谓词来实现表现层转换
-
-
重要概念
-
URI
-
HTTP请求谓词
-
JSON
-
flask-RestfulApi
- 基础结构
1 from flask import Flask 2 from flask_restful import Api, Resource 3 4 app = Flask(__name__) 5 api = Api(app) 6 7 # Resource资源。定义一个类继承程序的资源 8 class Hello(Resource): 9 10 # 请求方式:get请求 11 def get(self): 12 return {"hello": "get ok"} 13 # 请求方式:post请求 14 def post(self): 15 return {"hello":"post ok"} 16 # 请求方式:put请求 17 def put(self): 18 return {"hello":"put ok"} 19 # 请求方式:delete请求 20 def delete(self): 21 return {"hello":"delete ok"} 22 23 # 第一个参数代表资源;第二个参数代表路由 24 api.add_resource(Hello,'/') 25 26 27 if __name__ == '__main__': 28 app.run(debug=True)
1 # 不用装饰器的写法 2 # @app.route("/") 3 def index(): 4 return "Index" 5 # 参数:路由、描述、资源 6 app.add_url_rule("/index/","index",index) 7 8 if __name__ == '__main__': 9 app.run(debug=True)
- 拆分格式
- manage.py
1 """ manage.py """ 2 3 import os 4 from flask_migrate import MigrateCommand 5 from flask_script import Manager 6 from day05_chaiAdvanced import create_app 7 8 # 从系统环境中获取参数FLASK_ENV的值给env,判断是什么环境下的服务器 9 # 避免外人修改代码,方便代码放在什么环境服务器下,就在什么环境下运行 10 # 在系统终端 vim .bashrc 编写系统环境变量:#FLASK_ENV。export FLASK_ENV = "develop" 保存退出 11 env = os.environ.get("FLASK_ENV") or 'default' 12 13 # 首先创建一个flask对象、加载配置、加载扩展库、初始化路由 14 app = create_app(env) 15 16 # flask-scripy扩展 17 manager = Manager(app) 18 manager.add_command("db",MigrateCommand) 19 20 if __name__ == '__main__': 21 manager.run()
- __init__.py
1 ''' 启动项目的__init__.py ''' 2 from flask import Flask 3 4 from day05_chaiAdvanced.settings import Config, envs 5 from day05_chaiAdvanced.extension import init_ext 6 from day05_chaiAdvanced.views import init_api 7 8 def create_app(env): 9 10 # 创建Flask对象 11 app = Flask(__name__,template_folder="../templates") 12 13 # 加载初始化配置。 从类对象中加载。env参数确定在什么环境下的 14 app.config.from_object(envs.get(env)) 15 16 # 加载初始化扩展库。通过懒加载的方式加载(调用函数时参数的传递) 17 init_ext(app) 18 19 # 加载初始化api路由器。通过懒加载的方式加载(调用函数时参数的传递) 20 init_api(app) 21 22 return app
- views.py
1 from Book.route import books_api 2 3 def init_api(app): 4 books_api.init_app(app)
- books/route.py
1 from flask_restful import Api 2 3 from Book.views import BooksResource 4 5 books_api = Api() 6 7 books_api.add_resource(BooksResource, "/books/")
- books/views.py
1 from flask_restful import Resource 2 3 class BooksResource(Resource): 4 5 def get(self): 6 return {"msg": "book ok"}