现在的互联网架构大多是前后端分离,前后端人员技术都在各自的道路上越走越远,而联系前后端技术的唯一联系就是API,API文档变成前后端人员的纽带,swagger就是一款很好的API文档框架。
每个公司都有自己的API文档管理,如confluence,rap,gitlab的readme.md,而相对来说swagger显得更加轻量化,而整个互联网环境,从以前的整体结构到分层结构再到现在的微服务结构,一切的转变都在往越来越轻量化转变。
我之所以学习swagger是因为swagger-codegen可以自动生成api代码,让我只需要关系逻辑的实现,swagger-ui可以让我可视化测试api,swagger-editor方便书写api文档。
swagger-editor
首先需要学习swagger-editor,书写api文档,swagger-editor有线上版本 http://editor.swagger.io/。
1 | swagger: "2.0" |
2 | info: |
3 | version: 1.0.0 |
4 | title: CMDB API |
5 | description: CMDB API in swagger |
6 | license: |
7 | name: Apache 2.0 |
8 | host: localhost:5000 |
9 | basePath: /v1 |
10 | schemes: |
11 | - http |
12 | - https |
13 | consumes: |
14 | - application/json |
15 | produces: |
16 | - application/json |
17 | tags: |
18 | - name: Hosts |
19 | description: Collect hosts information |
20 | - name: Monitor |
21 | description: Monitor hosts metric |
22 | - name: Applications |
23 | description: Collect hosts applications |
24 | |
25 | paths: |
26 | /hosts: |
27 | get: |
28 | summary: List all hosts |
29 | operationId: listHosts |
30 | tags: |
31 | - Hosts |
32 | parameters: |
33 | - name: limit |
34 | in: query |
35 | description: How many items to return at one time |
36 | required: false |
37 | type: integer |
38 | format: int32 |
39 | responses: |
40 | 200: |
41 | description: An paged array of hosts |
42 | headers: |
43 | x-next: |
44 | type: string |
45 | description: A link to next page of response |
46 | schema: |
47 | $ref: '#/definitions/Hosts' |
48 | default: |
49 | description: unexpected error |
50 | schema: |
51 | $ref: '#/definitions/Ret' |
52 | post: |
53 | summary: Add a host |
54 | operationId: addHost |
55 | tags: |
56 | - Hosts |
57 | parameters: |
58 | - name: host |
59 | in: body |
60 | description: Add a host |
61 | required: true |
62 | schema: |
63 | $ref: '#/definitions/Host' |
64 | responses: |
65 | 201: |
66 | description: successful add |
67 | schema: |
68 | $ref: '#/definitions/Ret' |
69 | default: |
70 | description: unexpected error |
71 | schema: |
72 | $ref: '#/definitions/Ret' |
73 | delete: |
74 | summary: Delete a host |
75 | operationId: deleteHost |
76 | description: '' |
77 | tags: |
78 | - Hosts |
79 | parameters: |
80 | - name: host |
81 | in: body |
82 | description: Delete a host |
83 | required: true |
84 | schema: |
85 | $ref: '#/definitions/Host' |
86 | responses: |
87 | 200: |
88 | description: OK |
89 | schema: |
90 | $ref: '#/definitions/Ret' |
91 | default: |
92 | description: unexpected error |
93 | schema: |
94 | $ref: '#/definitions/Ret' |
95 | |
96 | /hosts/{hostId}: |
97 | get: |
98 | summary: Info for a specific host |
99 | operationId: showHostById |
100 | tags: |
101 | - Hosts |
102 | parameters: |
103 | - name: hostId |
104 | in: path |
105 | required: true |
106 | description: The id for the host |
107 | type: integer |
108 | format: int64 |
109 | responses: |
110 | 200: |
111 | description: Expected response to a valid request |
112 | schema: |
113 | $ref: '#/definitions/Host' |
114 | default: |
115 | description: unexpected error |
116 | schema: |
117 | $ref: '#/definitions/Ret' |
118 | |
119 | |
120 | definitions: |
121 | Host: |
122 | required: |
123 | - id |
124 | - hostname |
125 | - ip |
126 | properties: |
127 | id: |
128 | type: integer |
129 | format: int64 |
130 | hostname: |
131 | type: string |
132 | ip: |
133 | type: string |
134 | tag: |
135 | type: string |
136 | Hosts: |
137 | type: array |
138 | items: |
139 | $ref: '#/definitions/Host' |
140 | Ret: |
141 | required: |
142 | - code |
143 | - message |
144 | properties: |
145 | code: |
146 | type: integer |
147 | format: int32 |
148 | message: |
149 | type: string |
swagger_py_codegen
根据swagger文档生成代码框架:
安装:
1 | ~]# pip install swagger-py-codegen |
2 | ~]# swagger_py_codegen --help |
3 | Usage: swagger_py_codegen [OPTIONS] DESTINATION |
4 | |
5 | Options: |
6 | -s, --swagger, --swagger-doc TEXT |
7 | Swagger doc file. [required] |
8 | -f, --force Force overwrite. |
9 | -p, --package TEXT Package name / application name. |
10 | -t, --template-dir TEXT Path of your custom templates directory. |
11 | --spec, --specification Generate online specification json response. |
12 | --ui Generate swagger ui. # 生产swagger ui |
13 | --validate Generate swagger ui. |
14 | -tlp, --templates TEXT gen flask/tornado/falcon/sanic templates, # 支持4种框架 |
15 | default flask. |
16 | --version Show current version. |
17 | --help Show this message and exit. |
18 | ~]# swagger_py_codegen -s swagger.yaml cmdb -p demo-cmdb --ui --spec |
19 | ~]# tree cmdb |
20 | cmdb |
21 | ├── demo-cmdb |
22 | │ ├── __init__.py |
23 | │ ├── static |
24 | │ │ ├── swagger-ui |
25 | │ │ │ ├── css |
26 | │ │ │ │ ├── print.css |
27 | │ │ │ │ ├── reset.css |
28 | │ │ │ │ ├── screen.css |
29 | │ │ │ │ ├── style.css |
30 | │ │ │ │ └── typography.css |
31 | │ │ │ ├── fonts |
32 | │ │ │ │ ├── DroidSans-Bold.ttf |
33 | │ │ │ │ └── DroidSans.ttf |
34 | │ │ │ ├── images |
35 | │ │ │ │ ├── collapse.gif |
36 | │ │ │ │ ├── expand.gif |
37 | │ │ │ │ ├── explorer_icons.png |
38 | │ │ │ │ ├── favicon-16x16.png |
39 | │ │ │ │ ├── favicon-32x32.png |
40 | │ │ │ │ ├── favicon.ico |
41 | │ │ │ │ ├── logo_small.png |
42 | │ │ │ │ ├── pet_store_api.png |
43 | │ │ │ │ ├── throbber.gif |
44 | │ │ │ │ └── wordnik_api.png |
45 | │ │ │ ├── index.html |
46 | │ │ │ ├── lang |
47 | │ │ │ │ ├── en.js |
48 | │ │ │ │ ├── es.js |
49 | │ │ │ │ ├── fr.js |
50 | │ │ │ │ ├── it.js |
51 | │ │ │ │ ├── ja.js |
52 | │ │ │ │ ├── pl.js |
53 | │ │ │ │ ├── pt.js |
54 | │ │ │ │ ├── ru.js |
55 | │ │ │ │ ├── tr.js |
56 | │ │ │ │ ├── translator.js |
57 | │ │ │ │ └── zh-cn.js |
58 | │ │ │ ├── lib |
59 | │ │ │ │ ├── backbone-min.js |
60 | │ │ │ │ ├── handlebars-2.0.0.js |
61 | │ │ │ │ ├── highlight.7.3.pack.js |
62 | │ │ │ │ ├── jquery-1.8.0.min.js |
63 | │ │ │ │ ├── jquery.ba-bbq.min.js |
64 | │ │ │ │ ├── jquery.slideto.min.js |
65 | │ │ │ │ ├── jquery.wiggle.min.js |
66 | │ │ │ │ ├── jsoneditor.min.js |
67 | │ │ │ │ ├── marked.js |
68 | │ │ │ │ ├── swagger-oauth.js |
69 | │ │ │ │ ├── underscore-min.js |
70 | │ │ │ │ └── underscore-min.map |
71 | │ │ │ ├── o2c.html |
72 | │ │ │ ├── swagger-ui.js |
73 | │ │ │ └── swagger-ui.min.js |
74 | │ │ └── v1 |
75 | │ │ └── swagger.json |
76 | │ └── v1 |
77 | │ ├── __init__.py |
78 | │ ├── __pycache__ |
79 | │ │ ├── __init__.cpython-36.pyc |
80 | │ │ ├── routes.cpython-36.pyc |
81 | │ │ ├── schemas.cpython-36.pyc |
82 | │ │ └── validators.cpython-36.pyc |
83 | │ ├── api |
84 | │ │ ├── __init__.py |
85 | │ │ ├── __pycache__ |
86 | │ │ │ ├── __init__.cpython-36.pyc |
87 | │ │ │ ├── hosts.cpython-36.pyc |
88 | │ │ │ └── hosts_hostId.cpython-36.pyc |
89 | │ │ ├── hosts.py |
90 | │ │ └── hosts_hostId.py |
91 | │ ├── routes.py |
92 | │ ├── schemas.py |
93 | │ └── validators.py |
94 | └── requirements.txt |
95 | ~]# cd cmdb/demo-cmdb |
96 | ~]# python __init__.py |
97 | * Serving Flask app "__init__" (lazy loading) |
98 | * Environment: production |
99 | WARNING: Do not use the development server in a production environment. |
100 | Use a production WSGI server instead. |
101 | * Debug mode: on |
102 | * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) |
103 | * Restarting with stat |
104 | * Debugger is active! |
105 | * Debugger PIN: 119-925-026 |
访问 http://127.0.0.1:5000/static/swagger-ui/index.html 可以查看swagger-ui
添加简单的功能
虽然我们可以看到swagger-ui,也可以访问api接口,但是这样的接口没有实际的意义,我们需要自己定义实际的逻辑。
1 | # 逻辑处理的函数 cmdb/demo-cmdb/v1/api/hosts.py |
2 | # -*- coding: utf-8 -*- |
3 | from __future__ import absolute_import, print_function |
4 | |
5 | from flask import request, g |
6 | |
7 | from . import Resource, database |
8 | from .. import schemas |
9 | |
10 | |
11 | class Hosts(Resource): |
12 | |
13 | def get(self): |
14 | #print(g.args) |
15 | return database[:g.args.get('limit')], 200, {} |
16 | |
17 | def post(self): |
18 | #print(g.json) |
19 | database.append(g.json) |
20 | return {'code': 200, 'message': 'Add success'}, 201, None |
21 | |
22 | def delete(self): |
23 | #print(g.json) |
24 | database.remove(g.json) |
25 | return {'code': 200, 'message': 'Delete success'}, 200, None |
测试:
添加
查看
删除