1
matthewgao 2015-09-17 08:55:57 +08:00 via Android
通常用 json
|
2
crs0910 2015-09-17 08:56:33 +08:00
这是什么意思?不是 GET 和 POST 吗?
|
3
vainly 2015-09-17 08:57:09 +08:00
如果是 GET 请求,请求参数要在请求地址后"http://ip:port/doman?a=1&b=1&c=1"
如果是 POST 请求,而且交互使用 JSON 数据格式的话,参数传递会是这样的"{a:1,b=2,c=3,...}" |
4
mithvv 2015-09-17 09:22:22 +08:00
get
a=1&b=2&arr[]=3&arr[]=4 post { a:1,b:2,c:[3,4] } |
5
morethansean 2015-09-17 09:24:52 +08:00
POST 传出去不还是 a=1&b=c
除非你是自定义的 value 值是 json 格式比如 a=1&b=%7Bc%3A%205%7D > decodeURIComponent ('%7Bc%3A%205%7D') > "{c: 5}" |
6
jhaohai 2015-09-17 09:32:03 +08:00
json ,感觉已经成为标准了
|
7
wshcdr 2015-09-17 09:33:13 +08:00
json 已经是事实上的标准了
|
8
learnshare 2015-09-17 10:00:16 +08:00
JSON 几乎作为标准存在了,虽然数据量会大一些
|
9
temberature OP 相关的帖子
Json VS Protobuf https://www.v2ex.com/t/186561 IOS 开发怎么处理数据类型问题? https://www.v2ex.com/t/140470 为什么……不拿另一个 HTTP 服务器来当作数据库来给一个 Web App 使用? https://www.v2ex.com/t/120678 |
10
morethansean 2015-09-17 10:08:42 +08:00
不管你提交是否是 JSON ,转换总是需要的,特别是提交数据肯定是需要经过服务器端校验和安全处理的。
而且大多时候提交的数据又不是直接丢数据库去储存的,增删查找需要的字段,和返回的结果本来有些时候就相差甚远,处理逻辑也完全不一样,没必要强行 JSON 格式。 |
11
temberature OP @morethansean 我说的转换是指这两种字符串能表达的数据结构是等价的,如果只有一种,只需要在一种交换数据和程序变量之间转换。我没有说一定要用什么,只是想知道请教下是否有区别,以及各自的利弊又是什么?
|
12
temberature OP @learnshare 感觉都浪费在双引号上了
|
13
matthewgao 2015-09-17 10:33:15 +08:00
@vainly ”如果是 GET 请求,请求参数要在请求地址后"http://ip:port/doman?a=1&b=1&c=1" “ 这个似乎不是很符合 RESTful 的建议吧
|
14
lyz1990 2015-09-17 10:36:19 +08:00
json ,事实标准
|
15
temberature OP |
16
hantsy 2015-09-17 10:46:29 +08:00 6
@temberature 首先搞清楚什么是 REST 。
InfoQ 上有 Fielding 博士的原始论文的中文翻译版本。 广泛的讲 REST 不限于 HTTP 协议,数据交换格式可以是文本也可以是二进制。狭义的讲,我们通常将 REST 限于 HTTP , JSON 是取常用的数据交换格式, XML 也没问题。 REST 的几个要素: 1. 用一个唯一的 URI 代表资源的定位 2. 用 HTTP 语义( GET , POST , PUT , PATCH , DELETE , HEAD , OPTION 等)操作资源 3. 用 HTTP 状态标志操作结果 常用的 CRUD REST API 可以这样设计: 比如常见的 BLOG 程序,定义一个 /posts 入口。 /posts , GET , 取得所有 POST ,结果是一个 [{},{}]数组,可以接查询参数?page=XXX 等,返回 200 状态。 /posts , POST , 发布新 POST , Request Body 为{title:"text", body:"test body"}, 返回 201 状态。 /posts /{id}, GET , 取得所有单个 POST , URI 需要接 id, 成功返回 200 状态,失败 404 。 /posts /{id} , PUT , 更新 POST , Request Body 为{title:"text", body:"test body"}, 返回 204 状态。 /posts /{id} , DELETE , 删除 POST , 成功 返回 204 状态。 /posts 是对资源集合操作,/posts/{id}对单个资源操作。操作的结果有的有返回数据,更直接的表达结果是 HTTP Status 。 我写的简单的例子, https://github.com/hantsy/angularjs-springmvc-sample 这个例子,目前没写任何 Notes 来描述。 要了解 REST API 实现,可以看另外一个类似的例子 https://github.com/hantsy/angularjs-grails-sample , 这个项目的 WIKI 上的详细介绍。 @temberature 从 REST API 设计角度,你的问题和 REST 一点关系都没有。从设计上角度,查询数据?a=1 仅适用条件过滤,也就是上面第一个 /posts GET 方式。 另外,关于 REST API 设计好坏,有一个 Rechardson 成熟度模型来衡量。它定义了三个级别。国内几个一线大公司的 API 基本都是 Level 0 , 按这个标准衡量来讲,都不是 REST API ,虽然他们 Developer 网站都喜欢写上 REST 的字样。反而一些不大的公司做得不错,比如 JPUSH 等。 当我们考虑 Level3 ( Self-document, Self-Discovery ) 的时候,在交换格式上就有很多细节要去实现。这方面有一些行业标准或者正在标准化的交换格式。 如: HAL , Collection+JSON , JSON API 。 |
17
hantsy 2015-09-17 10:51:09 +08:00
@matthewgao GET 是用于查询操作,是可以使用 query parameters 的。
|
18
hantsy 2015-09-17 10:52:31 +08:00 1
@temberature JSON API 目前应用范围不广,不如 HAL 流行, Spring 目前只支持 HAL 。
|
19
refear99 2015-09-17 10:52:57 +08:00
取就用 get+query
增删改就用 POST DELETE PUT + json body |
20
temberature OP @hantsy 博士的论文我翻过几次,我知道数据交换并不是 rest 的主要关注点,只要想请教下在实际的做法以及如何取舍,感谢分享~
|
21
hantsy 2015-09-17 11:12:24 +08:00
@temberature 我上面两个链接的例子中 UI 全部是 SPA 。
|
22
gamexg 2015-09-17 11:28:38 +08:00
直接 command_json , sign 。
a=1&b=2 这种做 hash 签名容易被坑死。 |
23
temberature OP @gamexg 没太明白,能再具体解释下吗:)
|
24
loading 2015-09-17 11:56:21 +08:00 via Android
如果省流量你考虑进去,这问题就没必要讨论了。
hash 你后面掉坑就知道了。 |
25
temberature OP @loading 清楚利弊,在具体情况下就好取舍了吧;能描述下这个坑的大小、颜色、气味吗?以免掉下水道里,哈哈~
|
26
gamexg 2015-09-17 12:31:24 +08:00
比如一些 http 请求为了安全需要做 hash 签名, a=1&b=2 这种签名会碰到很多坑。
看一下这个 hash 签名设计: https://blog.yanke.io/she-ji-yi-tao-ji-yu-hash-qian-ming-yan-zheng-de-api/ ``` 因此我初步设计了一个签名机制,步骤如下: 将时间戳,随机串, TokenID ,和业务逻辑关键参数构成一个字典 将字典按照 Key 升序排序,然后按照 key1 value1 key2 value2 拼成一个连续字符串 将 Path 拼在前面, Token 拼在后面 将整个字符串做 SHA256 ,作为一个参数放回到请求中 服务器端接收到请求的时候也进行同样的处理,进行签名验证。 如果你曾经裸写过常见的第三方服务 API 调用的话,你会对这些步骤非常熟悉。 ``` 如果直接传递 json 字符串,直接 hash json 字符串即可,不用麻烦的拼接了。 |
27
temberature OP @gamexg 只理解到处理方式的差别,没看到坑
|
28
wangleineo 2015-09-17 12:48:48 +08:00 1
还是统一用 JSON 好些吧,用 Form 提交的话,多层数据怎么办?
|
29
FrankFang128 2015-09-17 12:49:53 +08:00
都支持就好了
|
30
temberature OP @FrankFang128 这样只是把问题抛给了调用接口方吧
|
31
hantsy 2015-09-17 12:56:33 +08:00
@gamexg 难道不用 HTTPS 吗?签名这东西,看着就吐,根本谈不上安全,如果你的 Token 被截取(没 HTTPS 所有数据传输都透明), Hacker 构造你这样顺序的签名有什么难的。这也是 oAuth2 去掉了签名,强制使用 HTTPS 的原因。
|
32
marginleft 2015-09-17 12:59:30 +08:00
|
33
pandada8 2015-09-17 13:00:14 +08:00
不是取决于 Accept 头的么……
|
34
pandada8 2015-09-17 13:04:40 +08:00
|
35
iyaozhen 2015-09-17 13:20:46 +08:00
这个取决于你的操作吧。 GET 获取数据,可以用 urlencode 传参。 POST 用于更改数据,传 json 更合适吧。
|
36
temberature OP @pandada8 如果接口是不同的人在写,那还要看是谁方便,有一套参考的规范会更好吧
|
37
aftereclipse 2015-09-17 13:41:51 +08:00
统一 HTTP POST , json 数据格式,客户端和服务端都好写,加解密也好做
|
38
vainly 2015-09-17 14:04:11 +08:00
@matthewgao 不是啊,对于指定参数的 GET 请求时这么做的。
比如这样: @GET @Path ("findById") public String findById (@QueryParam ("id")String id ); |
39
temberature OP @vainly 没看懂,╮(╯▽╰)╭
|
40
pandada8 2015-09-17 14:26:06 +08:00
@temberature 最后当然要统一了……之前先做好协定。
比如有 angular,superagent 之类的场合我倾向于使用 json 有些时候框架搭配用 jquery 发请求那就用 form-urlencoded. 总体而言就是怎么方便怎么来 ———— 实在决定不了么 来局昆特牌吧 |
41
gamexg 2015-09-17 14:28:20 +08:00
@temberature 你需要保证前后端的排序、编码等是一致的。记得有一篇 API 文档提到过,个别语言的排序和 API 服务器不一致,需要特殊处理。
@hantsy 即使上了 https ,我也会利用类似签名的方式而不会直接传递 API 密钥做身份认证的。例如目前对于设备的认证就是设备注册时分配一个 id 及密钥,每个请求都会被 hash 签名。密钥只会在设备注册时传递一次,之后不会传递,这个风险还是可以接受的。由于密钥不像密码,更换麻烦,后期即使加上 https ,也不会直接传递密钥。 |
42
railgun 2015-09-17 14:30:22 +08:00
json 适合用来描述复杂的数据格式
如果只是简单的数据,用哪个都无所谓 还是要从实际出发,比如有的接口是要传文件的,用 json 就不合适了 |
43
FrankFang128 2015-09-17 14:32:50 +08:00
@temberature 支持两种方式的话,就没有问题了呀。 调用方怎么都不会错,怎么叫推给他们。
|
44
FrankFang128 2015-09-17 14:39:39 +08:00
楼上说什么 JSON 是事实标准的说法有点问题,
application/x-www-form-urlencoded; 也是标准啊。 按 REST 来说,根据 Content-Type 的值为 application/x-www-form-urlencoded 还是 application/json 做下判断就好了。 |
45
temberature OP @FrankFang128 我的意思不是把麻烦推给他们,是把分析两种方式的利弊推给了他们;在接口方,我倾向在理想情况把一种实现好,毕竟现实中资源和精力是有限的;同意都是标准的说法,但是事实标准是可能存在的。
|
46
jokcy 2015-09-17 15:56:50 +08:00
@morethansean 你可以用 payload 的方式传数据
|
47
temberature OP @pandada8 有时候确实会遇到自己难以决定或者双方难以一致的问题,这时候我的态度就先实现一种(直觉有时候也管用),在使用经验增长之后,答案自然就有了。 ps :突然想到“约定大于配置”。
|
48
temberature OP @railgun 文件确实特殊;一个项目中应该都有复杂点的数据,统一的约定还是挺重要的吧
|
49
temberature OP @gamexg hash 时 json 字符串中的顺序也需要注意吧
|
50
temberature OP @jokcy 一直没太明白设计这个的目的
|
51
gamexg 2015-09-17 16:50:20 +08:00
@temberature 客户端是对序列化后的字符串签名,服务端是先验证签名后反序列化,所以不涉及 key 顺序的问题。
|
52
temberature OP @gamexg 也见过接口的字符串签名算法,其实也可以按 json 这种,不明白为什么要排序:)
|
53
FrankFang128 2015-09-17 17:34:22 +08:00
我觉得没必要 2 选 1 的,两种同时存在是 OK 的,也是更为常见的。
|
54
yield9tk 2015-09-17 17:44:34 +08:00
两种可以同属存在。不同的压缩方式,在 accept 中设置即可
|
55
railgun 2015-09-17 17:54:43 +08:00
@temberature 那就 json 吧,适配性好一点,扩展也方便
|
56
hantsy 2015-09-17 17:58:23 +08:00
@gamexg 一些 oAuth2 provider 提供了 JWT 支持, 连接的时候使用, Spring 内置了支持(只需要设置)。其他情况真的没看到签名的使用。国内 X 宝 X 度通篇的 Sign ,除了让 API 看起来像屎一样,如果它的加密方法和顺序被预先知道了,我不觉得是安全的。
如果你想做所有请求还要加密, X509 应该可以了吧。我想只有银行级的安全才会有这种要求。 |
57
Geoion 2015-09-17 18:16:12 +08:00
两个尖括号的流量也省。。。。。
|
58
temberature OP @Geoion 对于用户量亿级的服务,还是有大差别的吧
|
59
jokcy 2015-09-17 18:23:42 +08:00
@temberature content-type 不一样
|
60
hantsy 2015-09-17 20:28:16 +08:00
@temberature 针对 Mobile 原生程序(比如 Android , IOS )的某些场合可以绕开 HTTP ,特别图片等数据量大的东西,使用更底层的协议通讯,效率更高。其它文本类的,全部用 JSON ,所有平台都通用。
其实, REST API 的设计,只要参考 Github API , 或者 Heroku 的 API 就好了。设计好的 API ,从根到底下资源是一个树型结构,如 / 是根, /posts 是 Post 资源集合, /posts/2 是 ID 为 2 的单个资源,/posts/2/comments ,是指 ID 为 2 的 Post 下面的所有 Comments 。如果使用 HAL , 从根开始添加一些必要的 metadata 信息, 下面的所有的资源都应该是可以 Discovery 的,使用 HAL Browser 这样工具是可以可视化整个 API 结构,而不需要借助文档说明。 |
61
morethansean 2015-09-18 09:08:38 +08:00
@jokcy web 单页应用直接 form data 不好么。
|
62
jokcy 2015-09-18 09:57:49 +08:00
@morethansean 不是不好,而是根据你们自己的需求自己定义,你这边以 form 格式传后台就以 form 格式接收并转换,用 json 的好处就是如果你的后台用的是类似 node 这样天生支持 json 数据的,那么就无需转换了。
|
63
matthewgao 2015-09-19 10:48:20 +08:00
@hantsy 我再补充一下, REST 还要注意状态转移和等幂性
|
64
matthewgao 2015-09-19 10:49:53 +08:00
@hantsy 多谢,我之前还没看到任何标准和参考说道到这个是可以的,反倒刻意去回避这个
|