> ### api接口设计的最佳规范是 遵循restful 风格
> ### 规范是约定,目的是让开发者在同一种规则下面编写api接口,避免歧义
> ### 规范参照其他 , 但也不必完全遵循 , 设计出符合我们自己使用方便的规范即可
**url的设计:**
* 按照rest的理念 , 将一切视为资源
* url中不应该包含动词 , 以简单明了的名词作为url , 使得url 更加的语义化 , 减少url的长度
* 以HTTP动词 作为此次请求的动作类型
* tp中需要配合路由实现
**我们自己的项目:**
* 由于tp自带路由解析 , 我们可以自定义 语义化的url , 甚至使用强制路由模式 , 即每个请求都必须有对应的路由匹配,才能请求成功,否则404.
* 不使用传统的pathinfo模式 , 因为会暴露项目的应用路径
* 后台使用param()方式获取参数 , 避免出现参数获取不到的问题
> #### url设计最佳实践:
> 1、定义自己的路由文件 , 如有必要强制使用路由
> 2、查询:GET,创建:POST,更新:PUT,删除:DELETE
> 3、请求头和响应头一律使用json类型的数据格式 : Content-Type:Application/json,
> 4、对于同一个url名词可以对应多种操作 ,如下:
```
http://127.0.0.1/articles GET
http://127.0.0.1/articles/1 GET
http://127.0.0.1/articles POST
http://127.0.0.1/articles/1 PUT
http://127.0.0.1/articles/1 DELETE
```
那么后台对应的路由就该这样:
```
'URL_ROUTER_ON' => true,
'URL_ROUTE_RULES'=>[
['articles$' ,'Home/Index/index','',['method' => 'get']],
['articles$' , 'Home/Index/add','',['method' => 'post']],
['articles/:id$' , 'Home/Index/info','',['method' => 'get']],
['articles/:id$' , 'Home/Index/update','',['method' => 'put']],
['articles/:id$' , 'Home/Index/delete','',['method' => 'delete']],
],
```
**传输数据格式 :**
* 服务端与客户端数据传递使用json格式
* 请求参数和返回参数中,尽量不要参杂无用字段,即需要什么就传什么
* 对于每个字段的数据类型应该尽量严格区分,由于js是强语言类型,PHP是弱语言类型,字符串和数字对于PHP语法本身没什么影响,但是对于js却完全不同。
* 一个完整的api请求应该包含这几个部分:HTTP请求 = 请求方式 + 请求头 + 请求体;
* HTTP响应 = 状态码 + 响应头 + 响应体;
* 尽量避免null类型的字段,可以给个默认值 ""
> 数据传输最佳实践:
**HTTP请求:**
```
GET方式请求:
HTTP/1.1 GET www.xxx.com
Content-Type:application/json
a=1&b=3&c=tt
POST方式请求
HTTP/1.1 POST www.xxx.com
Content-Type:application/json
{
"a": 1,
"b":2,
"c" :"ttt"
}
```
| 参数 | 描述 |
| --- | --- |
| POST\|GET | 请求方式 |
| Content-Type:application/json | 传输数据格式 json类型 |
| a=1&b=3&c=tt <br> { "a":1, ... } | key-value 格式 <br> { } 格式 |
**HTTP响应:**
```
HTTP/1.1 200 ok
Content-Type:application/json
{
"data":[],
"message":"xxxxxxxxxxxx",
"errcode" : "xxxxxxxxxxxx"
}
HTTP/1.1 400 Bad Request
Content-Type:application/json
{
"message":"xxxxxxxxxxxx",
"errcode" : "xxxxxxxxxxxx"
}
```
| 参数 | 描述 |
| --- | --- |
| 200 \| 400 | 表述成功的状态码 \| 表示失败的错误码 |
| Content-Type:application/json | 传输数据格式 json类型 |
| data | 返回的数据 [ 错误的请求没有该字段 ] |
| message | 返回的提示信息 |
| errcode | 返回的信息代码 |
> 约定后台数据返回的固定格式:
异常或失败返回:
```
{
"message": "姓名必须",
"errcode": 1005
}
```
查询列表(不分页)返回:
```
{
"data": [
{
"id": 2,
"name": "dino",
"nickname": "sunny",
"mobile": "15205451022"
}
],
"message": "查询成功",
"errcode": 1000
}
```
查询单条记录:
```
{
"data": {
"id": 6,
"name": "dd_dino12121"
},
"message": "查询成功",
"errcode": 1000
}
```
查询分页列表返回:
```
{
"data": {
"total": 10,
"per_page": 1,
"current_page": 1,
"last_page": 10,
"list": [
{
"nickname": "sunny",
"name": "dd_0007",
"id": 14
}
]
},
"message": "查询成功",
"errcode": 1000
}
```
添加成功返回:
```
{
"data": [],
"message": "添加成功",
"errcode": 1001
}
```
编辑成功返回:
```
{
"data": [],
"message": "编辑成功",
"errcode": 1002
}
```
删除成功返回:
```
{
"data": [],
"message": "删除成功",
"errcode": 1003
}
```
> 数据格式的问题解决:
1、由于MySQL数据库本身的原因,默认会把数据库中的字段类型全部转为字符串,解决方法是 修改公共配置文件:
```
// 数据库连接参数
'DB_PARAMS' => array(
PDO::ATTR_STRINGIFY_FETCHES => false,
PDO::ATTR_EMULATE_PREPARES => false
),
```
2、使用模型获取器 , 自动将字段类型转为需要的格式