所以我正在尝试为我们的CMS添加一个新的,闪亮的REST Web服务。它应该非常接近REST“roules”,所以它应该使用GET / POST / PUT / DELETE和正确的逻辑URL。我的设计深受Apigee Best Practices的启发。
CMS管理一个类别树,其中每个类别可以包含许多文章。对于多语言项目,每种语言的类别都是重复的(因此任何文章都是其ID和语言ID的唯一标识符)。 结构在所有语言中都是相同的,只有位置可以变化(因此类别X包含每种语言中的类别Y和Z,但Y可以在语言1中的Z之前,反之亦然语言2)。创建新文章或类别始终也会创建所有语言的副本。删除工作方式相同,因此始终会删除所有语言的文章。
仅供参考:语言由其数字ID或其区域设置标识(如en_US
)。
(请在所有URI前面对前导/v1
进行成像;我已跳过它,因为它不会对此问题添加任何内容。)`
我目前的方法是使用这样的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更具可读性。但这会
我想最终得到一个解决方案,并倾向于使用区域设置。但是否值得冒着重叠区域的风险?
(您可以将langid=X
映像与以下locale=xx_xx
互换。)
在大多数情况下,API的客户端将希望获取给定语言的文章而不是全部。我可以通过允许GET参数并提供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布局,但是在背景中可能有意外的东西吗?
答案 0 :(得分:1)
前段时间我遇到了完全相同的问题,我决定将当地人置于一切之前。在消费内容时,阅读以下网址会更有意义:
/en/articles/1/
/en/authors/2/
/gr/articles/1/
/gr/authors/2/
比
/articles/en/1/
/authors/en/2/
/articles/gr/1/
/authors/gr/2/
为了解决“没有特定的语言环境”问题,我会使用一个关键字来引用所有可用的语言环境或默认的语言环境。所以:
/global/articles/
或
/all-locales/articles/
或
说实话,我喜欢全球化,因为他们阅读它们是有意义的。
/all/articles/
希望我能帮助
DELETE /global/articles/:id :) delete an article in all languages
答案 1 :(得分:0)
我最初的做法是将语言作为URL中的可选前缀,例如/en_us/articles
,/en_us/articles/:id
,但如果您不想使用语言标识符“污染”您的网址,则可以改为使用Accept-language
标头,方法与定义内容协商的方式相同RFC 2616。微软的WebAPI正在使用这种方法进行格式协商。