前言前后端分离开发已经是很流行的一个开发模式。前端开发不需要部署后端语言的环境,后端开发也不需要前端写好的任何程序。后端只管暴露各种 API 接口供给前端进行数据的增、删、改、查,不负责生成 HTML 页面,这种方式能够减轻后端任务让后端开发更加专注。尤其是在微服务的开发框架下, 前后端分离开发的模式应用更加广泛。本篇亦是在微服务的开发框架下的实践总结。
在微服务开发框架下,前端通常被设计成一个独立的微服务。前后端仅仅通过接口来协作,前端服务最终生成一个独立的 Docker 镜像来部署。在产品的核心微服务定义完成后,我们希望前后端 Service 同时开始开发,所以这里我们利用 Swagger 创建了一个基于 Node.js 的 Mock Server 作为前后端分离开发的工具。在后端服务没有完全实现的情况下, 使用 Mock Server 作为前端开发的支持工具, 来实现前后端同时开发的目的。
Swagger 综述Swagger 是一个简单但功能强大的 API 设计表达工具。目前几乎所有的编程语言,都能支持 Swagger。Swagger 包括库、编辑器、代码生成器等很多部分,这里我们主要用到了 Swagger Editor。Swagger 可以选择使用 JSON 或者 YAML 的语言格式来编写 API 文档。我们可以用任何文档编辑器来编写 Swagger API 文档,也可以选择使用 Swagger Editor。Swagger Editor 能够提供语法高亮、自动完成、即时预览等功能,非常强大。如图 1 展示的编辑功能,当我们修改了 API 的定义之后,在编辑器右侧就可以看到相应的 API 文档了。
图 1. Swagger Editor 编辑器我们可以使用在线版本来编辑,也可以非常简单地部署本地的 Swagger Editor,部署细节请参考 。Swagger Editor 不仅能很便捷地生成 API 文档,它还能够自动生成 Mock Server 所需要的代码。而本文实践采用的是其他生成 Mock Server 的方法,所以此处就不对自动生成 Mock Server 代码多做介绍了。
编写 Swagger API 文档Swagger API 文档遵循 OpenAPI 文档定义标准。文档内容使用 key:value 的格式。
当前后端共同定义好 API 接口后, 我们就可以利用 Swagger Editor 或者其他编辑器将 API 文档写出来。比如我们希望 Mock Server 的名字是 Docs API,host 为 localhost,端口 10010,所有 API 的共同前置路径为 /docs。其中一个 Rest API 定义为:
URL: /docs/note
Request:
Method: Get
Parameter: note
Type: string
In: path
Required: true
Respond:
200: Return success message
500: Return error message
|
依据上面的需求我们开始编写 API 文档,Swagger 文档大致可以分为以下四个大的部分:
- Swagger API 版本。目前 OpenAPI 最新已经到 3.0.1 版本。本文实践采用 2.0 版本。
- 基本定义。包括 Info Object,Server Object 等等,根据产品的需要添加相应的定义。具体代码参考清单 1:
清单 1. API 文档基本定义1
2
3
4
5
6
7
8
9
10
11
12
13
| info:
version: "0.0.1"
title: Docs API
host: localhost:10010
basePath: /docs
schemes:
- http
- https
consumes:
- application/json
produces:
- application/json
- text/html
|
- Paths 模块。包括 Path Item Object,Operation Object 等等,每一个具体的 Rest API 请求需要一个 Path Item Object。根据产品的需要添加相应的定义。对应 API URL /docs/note, 具体 Path 定义代码参考清单 2:
清单 2. API 文档 Paths 模块1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| paths:
/{filename}:
get:
description: Returns note special resource to the caller
parameters:
- name: filename
in: path
description: resource name
required: true
type: string
responses:
"200":
description: Success
schema:
required:
- message
properties:
message:
type: string
# responses may fall through to errors
default:
description: Error
schema:
required:
- message
properties:
message:
type: string
|
- Definitions 模块。复杂 Object 或者公用 Object 的定义可以写在 Definitions 模块,这样可以增强 API 文档的可读性。比如我们可以把 response 中 200 和 500 的定义抽取出来,定义 2 个 definitions,然后修改 Path 对应部分的代码。具体代码参考清单 3:
清单 3. API 文档 Definitions 模块1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| definitions:
GeneralResponse:
required:
- message
properties:
message:
type: string
ErrorResponse:
required:
- message
properties:
message:
type: string
……
/{filename}:
get:
…
responses:
"200":
description: Success
schema:
# a pointer to a definition
$ref: "#/definitions/GeneralResponse"
# responses may fall through to errors
default:
description: Error
schema:
$ref: "#/definitions/ErrorResponse"
|
Open API 支持的内容还有很多,此处只介绍和 Mock Server 相关的部分,其他 API 文档编写请参照 |