所以我正在尝试向我们的 CMS 添加一个新的、闪亮的 REST Web 服务。它应该非常接近 REST“规则”,因此它应该使用 GET/POST/PUT/DELETE 和正确的逻辑 URL。我的设计深受Apigee Best Practices的启发。
CMS 管理一个类别树,其中每个类别可以包含许多文章。对于多语言项目,每种语言的类别都是重复的(因此任何文章都由其 ID 和语言 ID 唯一标识)。所有语言的结构都是相同的,只是位置可以不同(因此类别 X 包含每种语言中的类别 Y 和 Z,但在语言 1 中 Y 可以在 Z 之前,而在语言 2 中则相反)。创建新文章或类别总是会创建所有语言的副本。删除的工作方式相同,因此始终删除所有语言的文章。
仅供参考:语言由其数字 ID 或语言环境(如en_US
)标识。
(请/v1
在所有 URI 前面画一个前导;我跳过了它,因为它对这个问题没有任何帮助。)`
我目前的方法是使用这样的 URL 方案:
GET /articles :( returns all articles in all languages
GET /articles/:id-:langid :) returns a single article in a given language
POST /articles :) creates a new article
PUT /articles/:id-:langid :) update a single article in a given language
DELETE /articles/:id :) delete an article in all languages
但...
如何识别语言?
目前,每种语言分配的区域设置不需要是唯一的,因此在极少数情况下两种语言可以具有相同的区域设置。使用 ID 保证是唯一的。
使用区域设置(很可能强制小写)会很好,因为 URL 更具可读性。但这会
- 可能会导致项目具有重叠的语言环境。
- 要求客户端首先获取语言环境(但我猜客户端无论如何都必须获取语言 ID,所以这没关系)。
我想最终得到一个解决方案,并倾向于使用语言环境。但是,是否值得冒重叠地区的风险?
(您可以在下面的图像langid=X
中互换locale=xx_xx
。)
语言应该是层次结构元素吗?
在大多数情况下,API 的客户端将希望获取给定语言的文章,而不是全部。我可以通过允许 GET 参数和 offer 来解决这个问题GET /articles?langid=42
。但由于这是一个常见的用例,我想避免使用可选参数并使其明确。
这将导致GET /articles/:langid
,但这引入了语言是 API 内部层次结构级别的概念。如果我要这样做,我想让其他动词保持一致。新的 URL 布局如下所示:
GET /articles/:langid :) returns all articles in a given language
GET /articles/:langid/:id :) returns a single article in a given language
POST /articles :( creates a new article in all languages
PUT /articles/:langid/:id :) update a single article in a given language
DELETE /articles/:langid/:id :( delete an article in all languages
或者
GET /:langid/articles :) returns all articles in a given language
GET /:langid/articles/:id :) returns a single article in a given language
POST /articles :( creates a new article in all languages
PUT /:langid/articles/:id :) update a single article in a given language
DELETE /:langid/articles/:id :( delete an article in all languages
这将导致...
如何处理全球行动?
上述布局存在适用于所有语言的问题POST
,DELETE
但 URL 表明它们仅适用于一种语言。所以我可以修改布局:
GET /articles/:langid :) returns all articles in a given language
GET /articles/:langid/:id :) returns a single article in a given language
POST /articles :) creates a new article in all languages
PUT /articles/:langid/:id :) update a single article in a given language
DELETE /articles/:id :) delete an article in all languages
这使得布局有些混乱,因为语言级别只是有时存在,并且需要对系统的内部有很多了解。从好的方面来说,这与系统非常匹配,并且与内部工作非常相似。
牺牲?
那么我在哪里做牺牲呢?我是否应该引入别名 URL 以获得良好的 URL 布局,但可能会在背景中做一些意想不到的事情?