我正在寻找一个关于如何序列化我的数据的约定,当我有一个(长)项目列表,我想要POST到服务器。
例如,如果我有一个资源/users
并且我想向它发布一个新资源,我会对新用户的字段进行http编码,并将其放在请求正文中,如下所示:{ {1}}
但如果我有一个用户列表,比如name=foo&age=20
,是否有传统的POST方式?
我在想[{ name: 'foo', age: 20 }, { name: 'bar', age: 10 }]
,但我找不到任何支持它的东西。 Web服务器通常接受/期望什么?
答案 0 :(得分:9)
可能会改变我的答案的快速问题:您是直接从HTML表单发帖还是期待更复杂的内容(例如javascript处理,甚至不是基于Web的客户端)
如果你有足够复杂的客户端,你可以构建一个JSON字符串和POST,其内容类型为application/json
。然后,无论处理什么资源,POST都可以使用任意数量的json库来读取已发布的字符串并按原样处理。
您使用哪些框架/语言来构建REST服务?他们是否有内置的功能/惯例来帮助您?
例如,如果您使用JAX-RS构建服务,则可以使用内置注释@FormParam来处理已发布的表单...例如:如果您发布了以下内容内容类型application/x-www-form-urlencoded
:name=foo&age=20&name=bar&age=10
您可以通过以下方式检索服务端的并行列表:
@POST
@Consumes("application/x-www-form-urlencoded")
public void createUsers(@FormParam("name") List<String> name, @FormParam("age") List<String> age) {
// Store your users
}
但是你必须处理如果一个列表比另一个更短/更长的问题,你如何解决?如果创建用户列表需要或可选的新字段会发生什么? (但正如我最初提到的,JSON对象的JSON数组将解决该问题...有许多库支持JAX-RS中的自动JSON反序列化,或者也可以选择创建自己的{{3 }}
(关于下一部分的免责声明:我不知道rails,我在Java服务领域的经验更多......我的基础是MessageBodyReader)。看起来Rails有一个name[]=foo&name[]=bar
的约定来自动处理发布的数据到数组中,并且类似于填充user[name]=foo&user[age]=20
等结构的约定......也许如果你在轨道上有一些方法可以使用/滥用这两个功能来获得理想的结果?
其他REST框架和语言可能有自己的约定和功能:)
答案 1 :(得分:1)
Rails将格式序列化为与您建议的格式不同的格式。如果你有一个嵌套模型,它会像这样编码:
name=theo&company[name]=acme
(等效的JSON为{"name": "theo", "company": {"name": "acme"}}
)
我不能说我已经看到Rails应用程序发送数组,但没有理由说它不起作用(最坏的情况是你最终会得到带字符串键的哈希)。
PHP有另一个约定,如果你想发送一个数组
names[]=alice&names[]=bob&names[]=steve
但我不知道你是怎么做嵌套对象的。
HTTP规范,或者如果它是URI规范,不确定哪个atm,实际上指定如果多次传递相同的参数,则获得值数组(而不是大多数应用程序框架的最后获胜行为)。您可以在Jetty的API文档中看到这一点,例如:http://api.dpml.net/org/mortbay/jetty/6.1.5/org/mortbay/jetty/Request.html#getParameterValues(java.lang.String)
但是,大部分内容适用于GET
次请求,不一定是POST
(但application/x-url-encoded
可能遵守与GET
相同的标准。
简而言之,我不认为这样做有 标准,POST
身体是一个狂野的西部领土。但是,我认为要么你应该使用JSON,因为它是用来描述结构的,application/x-url-encoded
不是,或者你应该尝试更好地表示数据的结构,如:
users[0][name]=foo&users[0][age]=20&users[1][name]=bar&users[1][age]=10
例如,开箱即用的Rails应用实际上可以解释这种可能性。