Get /users/2 Response 404
代表了请求ID为2的User,返回了404代表资源没有找到。
https://www.zhihu.com/question/28570307 最高票回答也解决了一些在设计rest API涉及的问题,例如某些动词很难去名词化,这要涉及到业务的抽象,词性的转换。另外比如像search这种有两种词性的,其实设计的时候已经可以作为URL的一部分了。这点在github API中已经有体现:
https://api.github.com/ "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
类似login这种,虽然有提到是在操作session,但是在实际应用中,一般就非rest的处理了,用/login作为endpoint,大家看起来也不会认为有很大的问题。
在业务系统中会遇到更加复杂的问题,其中包括
- 1. 一对多,多对多的rest API设计,包括创建,更新
- 2. 双向绑定的循环序列化问题。
这里先记录一下我看到的针对1这个问题的处理。
一般来说,这种关联分两种情况:
[list]
GET /persons/{PERSON_ID}/edu-histories
获取单个商品 GET /products/{product_id}
获取某个订单的所有商品 GET /orders/{order_id}/products
获取某个商品关联的所有订单 GET /products/{product_id}/orders
创建这种关联可以用POST/PUT/PATCH去实现,在body中加入被关联实体即可。具体实现在stackoverflow也有讨论应该用哪个method更符合规范,大家都比较提PATCH,实际应用中可以针对自己的web server支持不支持PATCH来做调整。
在这种情况下,实体尽量单独返回,不要返回关联实体,例如获取order,不会直接把关联的product返回来。这样造成的一个缺陷就是,需要client端调用多次才能返回所有的结果。
[/list]
这种缺陷其实是RestAPI原本设计理念的第三层 -- hateoas 所提及的,即,每个restAPI发回的结果可能不仅仅是当前的一个结果,它还应当包含对其他相关对象引用的link,就像我们去访问一个网址,网址上不仅仅会返回给我们内容,还会给我们提供其他相关的超级链接一样。 只有完成了Hateoas才能算是真正的Restful。
另外一种实现是把这种关联认为是一类资源,URL直接用relationship表示:
GET /order-product-relationship [{"orderId":1,"productId":2},{"orderId":1,"productId":3}]
待续