Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 REST Routes & Http Verbs

As a result of a previous question of mine, I have discovered two ways of handling REST routes in MVC3.

This is a followup question where I am trying to learn factual differences/subtleties between these two approaches. I am looking authoritative answer if possible.

Method 1: Single Route, with Action Name + Http Verb Attributes on Controller Actions

  1. Register a single route in Global.asax using a specified action parameter.

    public override void RegisterArea(AreaRegistrationContext context)
    {
        // actions should handle: GET, POST, PUT, DELETE
        context.MapRoute("Api-SinglePost", "api/posts/{id}", 
            new { controller = "Posts", action = "SinglePost" });
    }
    
  2. Apply both ActionName and HttpVerb attributes to controller actions

    [HttpGet]
    [ActionName("SinglePost")]
    public JsonResult Get(string id)
    {
        return Json(_service.Get(id));
    }
    [HttpDelete]
    [ActionName("SinglePost")]
    public JsonResult Delete(string id)
    {
        return Json(_service.Delete(id));
    }
    [HttpPost]
    [ActionName("SinglePost")]
    public JsonResult Create(Post post)
    {
        return Json(_service.Save(post));
    }
    [HttpPut]
    [ActionName("SinglePost")]
    public JsonResult Update(Post post)
    {
        return Json(_service.Update(post););
    }
    

Method 2: Unique Routes + Verb Constraints, with Http Verb Attribute on Controller Actions

  1. Register unique routes in Global.asax with HttpMethodContraint

    var postsUrl = "api/posts";
    
    routes.MapRoute("posts-get", postsUrl + "/{id}", 
        new { controller = "Posts", action = "Get",
        new { httpMethod = new HttpMethodConstraint("GET") });
    
    routes.MapRoute("posts-create", postsUrl, 
        new { controller = "Posts", action = "Create",
        new { httpMethod = new HttpMethodConstraint("POST") });
    
    routes.MapRoute("posts-update", postsUrl, 
        new { controller = "Posts", action = "Update",
        new { httpMethod = new HttpMethodConstraint("PUT") });
    
    routes.MapRoute("posts-delete", postsUrl + "/{id}", 
        new { controller = "Posts", action = "Delete",
        new { httpMethod = new HttpMethodConstraint("DELETE") });
    
  2. Use only an Http Verb Attribute on the Controller Actions

    [HttpGet]
    public JsonResult Get(string id)
    {
        return Json(_service.Get(id));
    }
    [HttpDelete]
    public JsonResult Delete(string id)
    {
        return Json(_service.Delete(id));
    }
    [HttpPost]
    public JsonResult Create(Post post)
    {
        return Json(_service.Save(post));
    }
    [HttpPut]
    public JsonResult Update(Post post)
    {
        return Json(_service.Update(post););
    }
    

Both of these methods let me have uniquely named Controller Action Methods, and allow for RESTful routes tied to the verbs... but what is inherently different about restricting the route vs. using a proxy action name?

like image 475
one.beat.consumer Avatar asked Jan 04 '12 02:01

one.beat.consumer


1 Answers

You won't get an authoritative answer by here are my 2 cents:

I prefer method 2 because then you have all your routing in one place. You can encapsulate your routing into a method e.g. MapResourceRoutes(string controller, string uri) and have it used muptiple times throughout your API.

Also method 2 gives you clearly named routes that you can use for linking and reverse routing.

like image 129
Kugel Avatar answered Nov 01 '22 01:11

Kugel