"True" REST routing via MVC 4 Web API

Richard A. picture Richard A. · Dec 29, 2012 · Viewed 7.5k times · Source

TL;DR Summary: Can I configure MVC Web API routing for HTTP GET, PUT & DELETE?

I've been looking into replacing our old Data Access Layer (a DLL based on DataSets and TableAdapters) with a private API, with a view to creating a public API if it's successful. I've done some work with MVC 4 to refresh our frontend, and loved working with it, so it seems sensible to explore the "Web API" project type before diving into WS- or WCF-based libraries.

An initial demo allows me to return XML/JSON nicely, for example:

//service.url/api/Users

... returns a list of users, while a specific user's details can be accessed via:

//service.url/api/Users/99

So far, so RESTful. However, in order to truly map URIs to resources I want to do an HTTP PUT (new user) or HTTP DELETE (remove user) to the the URI listed above. In all of the examples I've seen for these projects, along with the Scaffolds provided in Visual Studio, this convention is followed:

//service.url/api/Users/Create

//service.url/api/Users/Delete/99

//service.url/api/Users/Update/99

... and so on. This feels like side-stepping the issue to me, which is a shame when what's there has been put together so nicely!

Any thoughts on how best to approach this?

Answer

Erik Philips picture Erik Philips · Dec 29, 2012

What you want is the default in MVC Web API. I'm not sure what you are looking at but here is a great example of routing the Get/Post/Put/Delete to actions.

For example you may want:

public class UsersController : ApiController
{
  // GET http://service.url/api/Users/1
  [HttpGet]
  public User GetUser(int id);

  // POST http://service.url/api/Users/?name=richard...
  [HttpPost]
  public User AddUser(User model);      

  // PUT http://service.url/api/Users/?id=1&name=Richard...
  [HttpPut]
  public User UpdateUser(User model);

  // DELETE http://service.url/api/Users/1
  [HttpDelete]
  public User DeleteUser(int id);
}

I've explicitly set these, but the GetUser and DeleteUser don't need the prefix because they start with the matching HTTP method.