回答
这是程序员 StackExchange 中提出的一个问题,建议保持类名单一。我特别喜欢其中一个答案中的逻辑,“用来转动螺丝的工具称为“螺丝刀”而不是“螺丝刀”。 我同意。名称应保留为名词和形容词。
就路由而言,最佳实践似乎倾向于将路由作为复数名词,并避免使用动词。这个 Apigee博客说,“避免使用混合模型,在这种模型中,您对某些资源使用单数,而对其他资源使用复数。保持一致允许开发人员在学习使用您的 API 时预测和猜测方法调用。” 并建议根据流行网站的做法使用单数或复数。他们在路由中使用单数名词的唯一示例是 Zappos 站点,该站点以http://www.zappos.com/Product作为路由;但是,如果您检查该站点,它并不完全是产品资源的路径,而是一个查询,可能针对他们所有的产品。你可以输入http://www.zappos.com/anything并获得结果页面。所以我不会投入太多的股票。
来自 mwaysolutions(随机查找)的其他博客,例如“使用名词但没有动词”和“使用复数名词”。撇开其他观点不谈,大多数博客/文章倾向于说同样的话。复数名词,没有动词。
TL;DR:控制器使用单数名词,路由使用复数名词。
控制器
控制器和路由代表两个不同的概念。控制器是一个类或蓝图。与压模类似,我不会说我有一个UnicornsStamper
我会说我有一个UnicornStamper
可以制作独角兽邮票的,我可以用它制作一系列独角兽邮票。集合、作为位字段的枚举类型、作为属性集合的静态类(就像集合一样),以及可能我会使用复数名称的其他一些边缘情况。
路线
A(n) URL 是资源的地址,因此名称为Uniform Resource Locator。我不同意“路线是查询”的说法。路线可以包含查询(查询字符串)来缩小返回的资源,但路线是被请求的位置或资源。
随着属性路由的出现,控制器的多元化路由就像在声明中添加[RoutePrefix("quotes")]
属性一样简单。QuoteController
这也允许更容易设计关联路由。查看原始问题中提供的示例路线:
/quotes
GET: Gets all quotes
POST: Creates a new quote
/authors/shakespeare/quotes
Associative route in the QuoteController
GET: Gets all Shakespeare quotes
/quotes/new
This is a bad route IMO. Avoid verbs.
Make a POST request to '/api/quotes' to create a new quote
/quotes/shakespeare
/quotes/popular
Although these would be nice to have, they're not practical for routing (see below)
最后两条路线的问题在于,您没有简单的方法来区分流行引用和作者引用,更不用说通过名称或 ID 链接到引用的路线了。您需要用[Route("popular")]
后跟[Route("{author}")]
(按该顺序)修饰的操作,以便路由表以适当的顺序选择路由。但是作者路线消除了拥有路线的可能性[Route("{quoteName}")]
或[Route("{quoteId}")]
(假设quoteId
是一个字符串)。自然,您会希望能够按名称和/或 ID 路由到引号。
稍微偏离主题
最好通过关联路径来获取作者的引用。您仍然可以将流行的路由用作静态路由名称,但此时您正在增加路由复杂性,这将更适合查询字符串。在我的脑海中,如果我真的想在路线中包含流行的搜索词,我可能会这样设计这些路线:
a:/authors/{authorName}/quotes
b:/authors/{authorName}/quotes/popular
c:/authors/{authorName}/quotes?popular=true
d:/quotes/popular
e:/quotes/popular?author={authorName}
f:/quotes?author={authorName}&popular=true
g:/quotes/{quoteName|quoteId}
这些可以分散在QuoteController
的行动中。假设控制器有一个[RoutePrefix("quotes")]
属性:
[HttpGet]
[Route("popular")]
[Route("~/authors/{authorName}/quotes/popular")]
// Handles routes b, d, & e
public ViewResult GetPopularQuotes(string authorName)
return GetQuotes(authorName, true);
[HttpGet]
[Route("")]
[Route("~/authors/{authorName}/quotes")
// Handles routes a, c, & f
public ViewResult GetQuotes(string authorName, bool popular = false)
// TODO: Write logic to get quotes filtered by authorName (if provided)
// If popular flag, only include popular quotes
[HttpGet]
[Route("{quoteId}")]
// Handles route g
public ViewResult GetQuoteById(string quoteId)
// TODO: Write logic to get a single quote by ID
免责声明:我在脑海中写下了这些属性,可能存在需要解决的细微差异,但希望如何让这些路线发挥作用的要点能够通过。
希望这有助于消除关于控制器和路由命名约定最佳实践的一些混淆。最终,使用复数或单数控制器或路由的决定取决于开发人员。无论如何,一旦您选择了要遵循的最佳实践,请保持一致。