Handling Singular and Plural Controllers/Routes

后端 未结 5 1801
忘了有多久
忘了有多久 2021-01-31 09:12

I\'m a little confused on how I should handle singular and plural routes and controllers in my web application.

The website is a simple quotes site - think Einstein, Sha

相关标签:
5条回答
  • 2021-01-31 09:37

    Just because the default controllers of asp-mvc have singular names, it doesn't mean you should implement singular form for all your controllers.

    The correct answer is: it depends on the quantity of the entity that your controller represents.

    Singular, example the AccountController is singular because it represents actions (action method) pertaining to a single account only.

    Plural If your controller contains at least one action method that handles multiple entities at a single transaction.

    Example plural format

    users/update/3
    

    The route above makes you think you are editing all users, which does not makes sense if you read it like a sentence. However, if you read your route like query, it will make much more sense.

    If we think about it, a route IS a query: {entities}/{action}/{parameter} looks like a query to me.

    users/ shorthand of users/all reads "select all users table"

    users/123 reads "select single entity from users table"

    users/update/123 reads "update single entity from users table"

    Major sites use plural format, see sample below

    stackoverflow.com/questions          <- list of questions   (multiple)
    stackoverflow.com/questions/18570158 <- individual question (single)
    stackoverflow.com/questions/ask      <- new question        (single)
    
    stackoverflow.com/users        <- display list of users (multple)
    stackoverflow.com/users/114403 <- individual user       (single)
    
    asp.net/mvc/tutorials        <- display list of tutorials (multiple) 
    asp.net/mvc/tutorials/mvc-5  <- individual tutorial       (single)
    
    facebook.com/messages/     <- Display list of messages (multiple)
    facebook.com/messages/new  <- Create a single message  (single)
    facebook.com/messages/john <- view individual messages (multiple)
    

    I believe that English grammar should be strictly incorporated in every programming aspect. It reads more natural, and leads to good code hygiene.

    0 讨论(0)
  • 2021-01-31 09:42

    Good question. Some contributors to this site would recommend you try Programmers website, but I'm willing to attempt an answer to your question.

    Routing mechanism in ASP.NET MVC ,conceptually, is based on Resource-oriented architecture; the common guideline in ROA is

    Applications should expose many URIs (possibly an infinite number of them), one for each Resource (any resources in your applications should be unambiguously accessible via a unique URI)

    So, it's up to you to decide whether quote and quotes are two different resources or not.

    0 讨论(0)
  • 2021-01-31 09:46

    Answer

    Here's a question asked in programmers StackExchange that suggests keeping class names singular. I especially like the logic in one of the answers, "The tool to turn screws with is called "screw driver" not "screws driver"." Which I agree with. The names should be kept to nouns and adjectives.

    As far as routing goes, best practices seems to favor that routes be pluralized nouns, and to avoid using verbs. This Apigee blog says, "avoid a mixed model in which you use singular for some resources, plural for others. Being consistent allows developers to predict and guess the method calls as they learn to work with your API." and suggests using singular or plural based off what popular websites have done. Their only example for using singular nouns in the route is the Zappos site, which has http://www.zappos.com/Product as a route; but if you examine the site, it's not exactly a route to a product resource but is instead a query, probably for all their products. You can enter http://www.zappos.com/anything and get a results page. So I wouldn't put too much stock into that.

    Other blogs like this one from mwaysolutions (random find) say to "use nouns but no verbs" and "use plural nouns". Other points aside, most blogs/articles tend to say the same thing. Plural nouns and no verbs.

    TL;DR: Use singular nouns for controllers and plural nouns for routes.

    Controllers

    Controllers and routes represent two different concepts. The controller is a class, or a blueprint. Similar to a stamper, I wouldn't say I had a UnicornsStamper I'd say I had a UnicornStamper that makes a stamp of a unicorn with which I could make a collection of unicorn stamps with. Collections, Enum types that are bit fields, static class that is a collection of properties (acts like a collection), and probably a few other edge cases are where I'd use a plural name.

    Routes

    A(n) URL is an address to a resource, thus the name Uniform Resource Locator. I disagree that "a route IS a query". Routes can contain queries (query string) to narrow down returned resources but the route is the location or the resource(s) that's being requested.

    With the advent of attribute routing, pluralizing routes for controllers is as easy as adding a [RoutePrefix("quotes")] attribute to the QuoteController declaration. This also allows for easier design for associative routes. Looking at the sample routes provided in the original question:

    /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)

    The problem with the last two routes is that you have no simple way of differentiating between popular quotes and quotes by authors, not to mention that routes that link to quotes by name or Id. You would need actions decorated with [Route("popular")] followed by [Route("{author}")] (in that order) in order for the routing table to pick the routes up in the appropriate order. But the author route kills the possibility of having routes [Route("{quoteName}")] or [Route("{quoteId}")] (assuming quoteId is a string). Naturally, you'll want to have the ability to route to quotes by name and/or ID.

    Slightly Off Topic

    Getting quotes by author would best be done by an associative route. You could still probably get away with the popular route as a static route name, but at this point you're increasing route complexity which would be better suited for a query string. Off the top of my head, this is how I might design these routes if I really wanted to have the popular search term in the route:

    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}

    These could be spread across the QuoteController's actions. Assuming the controller has a [RoutePrefix("quotes")] attribute:

    [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

    Disclaimer: I wrote these attributes off the top of my head, there may be minor discrepancies that would need to be ironed out, but hopefully the gist how to get these routes to work comes through.

    Hopefully this helps to clear up some confusion on the topic of controller and routing best practices on naming conventions. Ultimately the decision to use plural or singular controllers or routes is up to the developer. Regardless, be consistent once you pick a best practice to follow.

    0 讨论(0)
  • 2021-01-31 09:49

    For WebAPI it should be plural. Microsoft has examples. In this examples for WebAPI it is plural. Here's links

    • https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-implementation (this is best practise),
    • https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

    • https://docs.microsoft.com/en-us/odata/webapi/built-in-routing-conventions

    In first example it is OrdersController . In last 2 pages there is ProductsController which is in plural. Also REST naming convention strict with that. Links should be in plural. So simple way to accomplish this in c# is to create controller with plural name

    As for MVC it should be singular controller

    0 讨论(0)
  • 2021-01-31 09:52

    Name of controller can be plural or singular based on the logic it executes. Most likely we keep controller name as singular because ProductController sounds little better than ProductsController.

       /product/list    or    /products/list
       /product/add   or    /products/add
    

    You can use both. But you must keep consistency and you should not mix them. Either all URL should be plural for every entity types or all should be singular.

    In ASP.NET sample, they have used Singular controller names Such as HomeController, AccountController. In case of HomeController you can't use HomesController because that no longer represents current site Home.

    With regards to logic, mostly we create Controller per database entity, in which we infer that Controller represents Actions to be performed on "Entity" So it is good to use Singular controller name and there is no harm.

    Only if you want to create set of Controller representing collection of something that should look like or map to plural database table names then you can name that as plural.

    0 讨论(0)
提交回复
热议问题