NEI 平台使用教程
20 分钟阅读
NEI 平台使用教程
规范化、自动化、云协作
内容介绍
- 基本概念
- 消息通知
- 接口测试
- 工程规范
- 构建工具
基本概念
* 项目组和项目
* 项目资源
* 数据模型
* 异步接口
* 页面
* 页面模板
* 规则函数
* 业务分组
项目组和项目
现代产品的基本形态
![](/public/nei/product-a.png)
项目组和项目
![](/public/nei/project-group.png)
项目组 - 默认分组
* 用户首次登录时,系统会自动创建一个叫“默认分组”的项目组
项目组 - 创建者
* 鼠标 hover 到项目组名称上,会显示该项目组的创建者
* 在“团队管理”中查看该项目组的创建者
项目组 - 锁定
* 项目组被锁定后,切换到“只读”状态
> 锁定后,项目引用的工程规范还能修改,工程规范也可以被锁定
项目组 - 团队管理
* 在“团队管理”中,可以把其他人添加到项目组中
>人是加到项目组上的,而不是在项目上
---
>可以将其他项目组的成员一并导入
项目组 - 成员权限
* `创建者`:拥有所有操作权限
* `管理员`:拥有除删除项目组之外的所有操作权限
* `开发者`:拥有项目资源的所有操作权限,对项目组本身没有操作权限
* `测试者`:同“开发者”
* `观察者`:“只读”权限
>除创建者外,其他角色都可以有多个
项目组 - 加入项目组
* 访问没权限的项目组或者项目时,会出现“申请加入”的按钮
>`搜索项目组/项目`:点击“我的项目组”,在“我的申请列表”区域的搜索框中输入项目组或者项目的名称
项目组 - 公共资源库
* 对于某个产品,有些资源对所有项目都是适用的,比如用户模型 User,登录接口等
```json
/* User Model */
{
"id": "[number]",
"name": "[string]",
"email": "[string]"
}
```
* 公共资源库,用来存放所有项目共享的资源,避免创建重复资源,以达到资源复用的目的
> 功能单一的资源才适合放到公共资源库
项目组 - 公共资源库
* 在创建项目组的时候,系统会自动创建“公共资源库”
* 公共资源库中的资源会出现在所有项目中
>前面有黄色共享图标的表示是共享资源
---
>公共资源库只有异步接口、数据模型和规则函数
---
>`不要把公共资源库当作实际项目来使用`
项目组 - 共享资源
* 项目中的异步接口、数据模型、规则函数可以共享
* `资源被共享后,无法取消共享`,操作时须谨慎
> 共享资源的时候,还会将它所有引用的资源一并共享
---
> `如果不小心共享了某个资源,可以把它复制到目标项目,然后再将其删除`
数据模型
数据模型
* 最强大的功能之一,其他资源可以引用
* 修改时,所有引用它的资源都会更新,即引用并不会产生新的数据模型,数据库只存了一份数据
数据模型 - 用途
* 描述数据库实体,比如 Project、Page 等
* 复用,比如需要在多处使用的异步接口响应参数,它们有着相同的格式
>正确合理地使用数据模型,可以为之后的其他功能做好准备
数据模型 - 类别
共有七大类别,涵盖了编程语言的常见数据类型:
* 哈希
* 枚举
* 数组
* 字符
* 数值
* 布尔
* 文件
>在新建数据模型时,请选择相应类别的单选按钮
数据模型 - 哈希
最常见的类型,比如 NEI 中的 Project:
```json
/* Project Model */
{
"id": "[number]",
"name": "[string]",
"type": "[string]",
"creator": "[user]",
"createTime": "[number]",
"progroupId": "[number]",
"toolKey": "[string]",
"description": "[string]"
}
```
> 字段的类型可以是任何数据模型,比如 creator 的类型是自定义类型 user
数据模型 - 哈希 - 可变字段
在定义时,有时某个字段的类型还无法确定,比如统一的异步接口返回参数格式:
```json
{
"code": "[number]",
"message": "[string]",
"result": "[variable]"
}
```
为了满足不同的应用场景,result 字段的类型可以是数组,也可以是对象,它的类型是 `variable`,表示类型是可变的。
>在使用这种数据模型时,需要明确指定 result 字段的类型
数据模型 - 哈希 - 创建方式
* 在第一行的第一个输入框,`粘贴JSON字符串`
* 点击`导入JSON`按钮,和上述功能相同
* `导入其他数据模型`:会将导入的字段当作一个整体来对待,详情页面也做了特殊显示处理
* `从接口导入`:会识别接口返回的 JSON 数据,支持 GET 和 POST 两种类型的接口
* `从JavaBean文件导入`
数据模型 - 枚举
枚举的类型可以是字符串或者数值,枚举的值是必填的,键是选填的。比如 NEI 中的 `ProjectType`:
| 值 | 类型 | 键(可选) | 描述 |
| :--- | :--- | :--- | :--- |
| 0 | number | | 常规项目 |
| 1 | number | | 公共资源库 |
| 2 | number | | 隐藏项目 |
>类型也可以是自定义的字符串或者数值
数据模型 - 枚举
包含键名的枚举类型 `HttpStatusCode`:
| 值 | 类型 | 键(可选) | 描述 |
| :--- | :--- | :--- | :--- |
| 200 | number | SUCCESS | 成功 |
| 500 | number | FAIL | 失败 |
>键在生成模型代码时会用到
数据模型 - 枚举 - 创建方式
* `导入其他枚举类型`
* `从JSON导入`,此时导入的是值
数据模型 - 数组
NEI 中的数组有两种表示方式:
* 在定义某个字段时,先选择类型 `Array`,多出来的另外一个下拉选择框表示数组元素的类型
* 直接定义数组类别的数据模型
>第一种表示方式是第二种的简便运用,两种表示方式是等价的
数据模型 - 数组 - 多维数组
NEI 也支持多维数组的定义:
* 数组元素的类型如果是数组,即可表示多维数组
数据模型 - 数组 - 创建方式
* `从JSON导入`
* `从接口导入`
数据模型 - 字符、数值、布尔
* 为了满足不同的开发人员的需求,NEI 可以自定义基本数据类型,比如 Objective-C 的 NSString、NSNumber 等
>自定义数据模型的使用方式和系统预置的相同
---
>等价用法:使用系统的 String,在“变量映射”中增加 `String -> NSString` 的规则
数据模型 - 文件
* 文件类型主要用在上传文件的接口中,在接口测试界面中也会有相应体现
功能:MOCK 数据
数据模型、异步接口的请求及响应参数、页面模板的参数等,系统提供了 MOCK 数据展示,优先级关系如下:
>`默认值 > 生成规则 > 随机数据`
---
>生成规则可以是合法的 JavaScript 脚本代码,但建议使用调用规则函数的代码,函数可以复用,管理维护也更方便
---
>枚举类型的 Mock 数据是其中的某个值
规则函数
规则函数
* 指 JavaScript 函数,定义时需要指定函数名和函数体
* 参数需要通过 `arguments` 对象获取,请参考 [arguments对象说明](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments)
规则函数 - 分类
* `生成规则`:参数的 Mock 数据
* `发送规则`:异步接口的发送前调用规则
* `接收规则`:异步接口的返回后调用规则
>不同类型的规则函数,注入的参数是不同的,请参考 [NEI平台规则函数使用说明](https://github.com/NEYouFan/nei-toolkit/blob/master/doc/NEI%E5%B9%B3%E5%8F%B0%E8%A7%84%E5%88%99%E5%87%BD%E6%95%B0%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)
规则函数 - 系统预置规则
为了区别自定义的规则函数,系统预置的规则函数都挂在 `NEI` 对象下,目前共有 10 个,更多信息请参考[文档](https://github.com/NEYouFan/nei-toolkit/blob/master/doc/NEI%E5%B9%B3%E5%8F%B0%E8%A7%84%E5%88%99%E5%87%BD%E6%95%B0%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md):
* `NEI.num()`,生成随机数字
* `NEI.url()`,生成随机URL地址
* `NEI.chinese()`,生成随机中文字符串
* `NEI.email()`,生成随机邮箱地址
* `NEI.id()`,生成唯一标识
* `NEI.str()`,生成随机字符串
* `NEI.bool()`,生成随机布尔值
* `NEI.var()`,生成随机类型的值
* `NEI.repeat()`,生成指定元素个数的数组
* `NEI.loop()`,生成指定层数的数据
异步接口
异步接口
最核心的项目资源,它包含以下信息:
* 请求地址、方式
* 请求头信息
* 请求参数
* 发送规则
* 响应头
* 响应结果
* 接收规则
话题:RESTful API 设计概要
* 资源“增删改查”的标准,使用 json 通信
* 以 User 实体为例,它的“增删改查”的接口分别是:
* 获取列表:`GET /users/`
* 获取单个:`GET /users/:id`
* 单个创建:`POST /users/`
* 批量创建:`POST /users/`
* 更新单个:`PATCH /users/:id`
* 删除单个:`DELETE /users/:id`
* 删除多个:`DELETE /users/?ids=id1,id2,...`
话题:RESTful API 设计概要
NEI 项目中的一些实践:
* 统一使用复数(users),统一使用小写
* url 前面可以加限定,比如 `/api/users/`
* url 中不出现动词,比如 `/deleteUser/`
* DELETE 的请求体有些代理会不识别,最好放在 url 中
* 详细的操作动词放到查询参数中,比如更新 user 头像:
* `PATCH /users?changeavatar`
话题:RESTful API 设计概要
使用正确的 http 响应状态码,常见的有:
* `200,OK`,操作成功
* `201,OK`,创建成功
* `204,OK`,删除成功
* `400,Bad Request`,请求无效
* `401,Unauthorized`,未授权
* `405,Method Not Allowed`,方法不允许
* `500,Internal Server Error`,服务器异常
话题:RESTful API 设计概要
* NEI 默认对 RESTful API 支持良好
* 内置了常见的请求方式:GET、POST、DELETE、PUT、PATCH 等
* 数据模型有 CRUD 的功能,可以一键生成相应的“增删改查”接口
异步接口 – 请求地址、方法
* 在创建异步接口时,需要指定请求地址,比如 /users
>在填写访问地址的时候,只要写相对地址即可,host 的值由环境决定,比如:
* 本地 http://127.0.0.1/users
* 线上 https://nei.netease.com/users/
* 请求方法一般使用系统内置的方法即可:GET、POST、DELETE、PUT、PATCH 等
异步接口 – 请求头、请求参数
* `请求头`即发送请求时添加到 Request Headers 中的参数
* `请求参数`即要发送的数据,默认是哈希对象
>JSON 共有 6 种类型:string、number、boolean、null、object、array。除了 null 之外,其他类型 NEI 都支持
异步接口 – 响应头、响应参数
* `响应头`即服务器需要返回的头信息
* `响应参数`即异步接口返回的数据
异步接口 – 响应参数定义技巧
* 响应参数的格式一般是固定的,可以定义一个通用的 ResultData 数据模型,它的结构如下所示:
```js
{
"code": "[number]", // 请求返回的状态码
"msg": "[string]", // 返回的信息
"result": "[variable]" // 真正的数据部分, 类型可变
}
```
* 点击“导入”按钮,选择 ResultData,然后再选择 result 的具体类型,比如它是一个数组,数组的每一项都是一个 User 对象
异步接口 – 响应参数定义技巧
某些接口返回的参数格式可能是这样的:
```json
{
"code": "[number]",
"message": "[string]",
"result": {
"data": "[variable]",
"total": "[number]"
}
}
```
即 result 是一个对象,除了数据部分外,还包括了一些其他信息,但字段名称不确定,所以无法使用通用的格式
异步接口 – 响应参数定义技巧
* 可以使用二级参数,result 字段的类型选择为 Object
>老版本的 NEI,无法很好地支持这个功能:需要给每一种响应增加一种数据模型,很繁琐,而且新增的数据模型无法复用,数据模型本身也没有意义
异步接口 – 发送、接收规则
* `发送规则`:在发送数据之前,对数据进行一些特殊处理,比如对密码进行加密等
* `接收规则`:在服务器返回数据后,对数据进行一些特殊处理后再返回给客户端脚本代码
页面
页面
* 指可以通过地址访问的普通页面,它主要包含了:
* 访问地址
* 参数列表
* 模板列表
* 接口列表
页面 - 访问地址
* 和异步接口类似,也使用相对地址
页面 - 参数列表
有两种传递方式:
* GET:通过 url
* POST:通过 form 表单
比如,定义了参数 userId,此时页面的开发人员就知道,访问该页面的时候将会传入 userId 参数,即访问地址是:http://127.0.0.1?userId={userId} ,根据 userId 参数可以做一些相应的业务逻辑
页面 - 模板列表
* 每张页面至少有一个模板
* 模板需要模板引擎来解析生成 html,常见的模板引擎有 freemarker、velocity、ejs 等
* 创建时无需填写扩展名(.ftl、.vm、.ejs 等),扩展名在工程规范中指定
* 一张页面可以有多个模板,每个模板表示页面的某种状态,比如`成功`、`失败`等状态,服务端根据业务逻辑返回相应的模板
>如果模板没有被页面引用,则构建工具不会生成这个模板文件
页面 - 接口列表
* 只是表明该页面会用到哪些异步接口
页面模板
页面模板
* 服务端的模板文件,主要包含了:
* 文件路径
* 预填数据
页面模板 - 文件路径
* 在使用构建生成模板文件时,存放的`相对于模板根目录的路径`
>`模板根目录`在工程规范中设置
页面模板 - 预填数据
* 服务端 Controller 注入给模板的数据,模板引擎会根据自己的语法规则,替换掉相应的插值变量
业务分组
业务分组
* 一个项目可以有多条业务线,业务分组可以用来更好地管理资源,它是唯一的
>和标签不同:资源可以有多个标签,但只能属于一个分组
消息通知
消息通知
* 个人消息
* 系统消息
* 新版本发版,新功能上线,活动等
消息通知 - 个人消息
* 规范
* 创建的规范被他人收藏
* 收藏的规范被他人删除
* 收藏的规范被他人取消了共享
消息通知 - 个人消息
* 项目组
* 项目组被创建者删除
* 自己已加入项目组
* 自己被移出项目组
* 自己被拒绝加入项目组
* 有其他人申请加入项目组
* 有其他人已加入项目组
* 项目组被更新
消息通知 - 个人消息
* 项目
* 有人创建了项目
* 有人删除了项目
* 有人更新了项目
消息通知 - 个人消息
* 资源的新建、更新、删除,需要通知该资源的负责人
>如果负责人是操作者本身,则不用通知
---
>如果没有负责人,则不用产生通知
---
>异步接口、页面模板和数据模型,需要通知引用它的资源的负责人
接口测试
接口测试
* 根据接口定义,验证接口实现的正确性
* 填写服务器地址
* 填写请求数据
* 填写期望值和出错提示,选填
* 批量运行测试用例,方便回归
>目前会检测字段类型、期望值、字段缺失等情况,测试完成后会有详细的测试报告
接口测试 - 开发计划
* 依赖测试:前一个接口的返回作为后一个接口的输入
* 对接 JIRA:测试失败时可以提 bug 到 JIRA 系统
* 其他需求收集中...
工程规范
工程规范
* 定义了工程的初始化结构,构建工具会按照定义数据在本地生成相应的结构
工程规范 - 实现原理
![工程规范 - 实现原理](/public/nei/spec.png)
工程规范 - 和项目关联
* 在项目的“工具设置”中,可以分别指定项目的“WEB、Android、iOS 和 测试”工程规范
>工程规范也可以当做脚手架来使用
工程规范 - 变量映射规则
* 在生成代码时,可以将某种类型映射成另外一种类型,比如将所有的 `String` 映射成为 `NSString`
* 可以在三个地方设置变量映射规则,优先级关系如下:
>`项目 > 项目组 > 工程规范`
工程规范 - JAR 包映射规则
* 对于 Java 项目,在 ftl 模板中可以直接调用 JAR 包提供的静态方法,比如 `StringUtil.highlight()` ,此时需要建立注入模板的实例名和类名的映射关系,比如:
| 实例名 | 类名 |
| :--- | :--- |
| `StringUtil` | `com.netease.util` |
话题:fmpp 加载 JAR 文件
有两种方法:
* 在 ftl 模板通过 pp.loadData 加载:
```html
<#assign Util=pp.loadData('eval', '
return new Util();
')>
```
* 通过配置文件的 data 属性添加:
```json
data: {
{"Util":eval('new Util();')}
}
```
> NEI 使用的是第二种方式
工程规范 - 分享
* 可以分享工程规范,对所有用户可见
>如果只想对项目组内用户可见,只要在“工具设置”中关联该工程规范即可
工程规范 – 特殊目录
* `静态资源根目录`:在使用本地模拟容器时,需要该信息,该目录用来存放静态资源
* `模板根目录`:在使用本地模拟容器时,需要该信息,该目录用来存放页面模板
* `接口MOCK数据根目录`:构建工具生成的异步接口的mock数据会放到该目录下面
工程规范 – 特殊目录
* `模板MOCK数据根目录`:使用本工具生成的页面模板的mock数据会放到该目录下面
* `JAR包根目录`:存放自定义JAR包,ftl模板可以直接调用JAR包中的静态方法
工程规范 – 特殊文件
* `接口列表填充`:每个异步接口都会生成一个文件
* `数据模型列表填充`:每个数据模型都会生成一个文件
>为了保持通用性,区分了枚举类型和非枚举类型。如果需要使用枚类型的数据类型列表,需要在文件名后面加上`!!enum`
* `页面模板列表填充`:每个页面模板都会生成一个文件
工程规范 – 特殊文件
* `视图列表填充`:每个视图都会生成一个文件
* `命令行参数配置文件`:该文件的内容须为有效的 json,它的值会作为本构建工具的命令行参数
* `自定义Handlebars辅助函数`:构建工具会运行这个文件,注册自定义方法
工程规范 – 命令行参数
命令行参数的值来自三部分:
* `终端输入的命令行参数`:指的是用户在命令行中输入的参数,可以是用于构建工具自身的参数,也可以是用于模板填充的数据
* `在项目中设置的命令行参数列表`
* `在工程规范中指定的命令行参数文件`:文件的内容须是有效的 json。如果指定了多个这样的文件,则取第一个文件的内容
工程规范 – 命令行参数
三者的优先级关系如下:
> `终端输入的命令行参数` > `在项目中设置的命令行参数` > `在工程规范中指定的命令行参数文件`
工程规范 – 模板数据
* 传给模板的数据格式说明请参考:
* [传给模板的数据说明](https://github.com/NEYouFan/nei-toolkit/blob/master/doc/传给模板的数据说明.md)
* Handlebars 辅助函数集说明:
* [Handlebars辅助函数集](https://github.com/NEYouFan/nei-toolkit/blob/master/doc/Handlebars辅助函数集.md)
构建工具
构建工具
* 地址:[https://github.com/NEYouFan/nei-toolkit](https://github.com/NEYouFan/nei-toolkit)
* 主要功能:
* 根据 NEI 平台定义的工程规范,生成工程的初始化目录结构
* 自动集成在 NEI 上定义的资源:页面、异步接口、数据模型、页面模板、业务分组等
* 本地模拟容器
构建工具 - 安装
* 通过以下命令安装构建工具:
>`npm install nei –g`
---
>构建工具基于 Node.js 平台,安装的 Node.js 版本须为 v4.2 及以上
构建工具 - build
* 根据定义的工程规范,生成工程的初始化结构,指令:
>`nei build -k [key] [参数]`
---
>项目有唯一的 key,通过这个 key 可以加载项目的数据
---
>工程规范也有唯一的 key,参数为 `sk`
构建工具 - update
* 更新通过 nei build 构建的项目,指令:
>`nei update [参数]`
---
>可以先在本地创建项目目录,然后在该目录下使用 `nei build` 和 `nei update` 命令,使用默认值即可
构建工具 - server
* 启动内置的本地模拟容器,指令:
>`nei server [参数]`
---
>本地模拟容器会 Mock 定义好的异步接口和页面,也会返回按照定义生成的 Mock 数据,从而使得前后端并行开发成为可能,更多信息请参考:[使用 NEI 进行前后端并行开发](https://github.com/NEYouFan/nei-toolkit/blob/master/doc/%E4%BD%BF%E7%94%A8NEI%E8%BF%9B%E8%A1%8C%E5%89%8D%E5%90%8E%E7%AB%AF%E5%B9%B6%E8%A1%8C%E5%BC%80%E5%8F%91.md)
构建工具 - server.config.js
* 根据工程规范的设置生成的配置文件,一般不用更改
>配置参数的含义请参考注释说明
构建工具 - server.config.js - routes
示例:
```js
routes: {
//"ALL /api/*": "代理所有接口, 这里输入代理服务器地址",
"GET /user/profile/:id": { name: 'mypage', index: 0, list: [{"id":10686,"path":"page/test"},{"id":10758,"path":"error"}] },
"POST /api/category/add": { path: 'post/api/category/add/data', id: 14077 },
"GET /api/category": { path: 'get/api/category/data', id: 14413 },
"POST /api/category": { path: 'post/api/category/data', id: 14076 },
"GET /api/author": { path: 'get/api/author/data', id: 14072 },
}
```
构建工具 - server.config.js - routes
>打开 `"ALL /api/*"` 可以将所有的接口代理到同一个地址,方便在不同的环境间进行切换
---
>有 `list` 的表示是页面,值是页面模板列表,显示哪个模板由 `index` 的值决定
构建工具 - template
* 解析本地模板,并生成新文件,指令:
>`nei template [参数]`
---
>模板解析引擎是 Handlebars
本文档在线访问地址
[http://gzool.com/nei](http://gzool.com/nei)
Thank You
Q & A
[包勇明](https://github.com/huntbao) / [@huntbao](http://weibo.com/gzooler)
留下评论