Reputation: 8695
We have a project that uses classic MVC controllers and WebAPI controllers. The classic controllers just serve up HTML. Any data gets passed around using WebAPI.
My co-worker pointed out that RESTful URLs identify resources and the GET/POST/PUT/DELETE are the verbs. I am curious if we should be following the same conventions for the pages themselves.
I am finding it really difficult to name the pages using RESTful conventions. For instance, the only thing that distinguishes an Index vs a Create vs an Edit page is whether or not the route includes an ID or query string. Before, I just had /Account
, /Account/Create
and /Account/Edit
. With REST, everything goes under /Account
and I have to distinguish based on IDs or query strings. I feel like I shouldn't be using RESTful conventions for naming pages.
Any data being transferred in the application uses WebAPI. So, for an account, we'd have these actions available:
GET /accounts - Gets all the accounts
GET /accounts/123 - Gets the account with the ID 123
POST /accounts - Creates a new account
PUT /accounts/123 - Updates account with ID 123
DELETE /accounts/123 - Delete account with ID 123
Some times the PUT method assumes the ID is in the body.
The HTML is returned by normal MVC controllers. In this case, there is only ever GETs. The HTML is almost completely static (we store IDs in hidden fields). AJAX is used to load the data using the REST API.
I am wondering if the HTML pages should use REST-like URLs or if I should use URLs found in older MVC projects. This is what was proposed by a co-worker:
GET /accounts - Gets a screen with all of the accounts
GET /accounts/123 - Gets the HTML for viewing a single account
GET /accounts - Gets the HTML for creating a new account (already in use!)
GET /accounts/123 Gets the HTML for updating an account (already in use!)
Since GET is always the HTTP method, I need something more than just a URL to distinguish screens. With old MVC routes, the action was part of the URL:
GET /accounts/Index - Gets the screen with all of the accounts
GET /accounts/Index/123 - Gets the screen for a single account
GET /accounts/Create - Gets the screen for creating an account
GET /accounts/Edit - Gets the screen for editing an account
Some of the answers point out that HTML pages are just resources. In my mind, they are just views, but are not yet a true representation of another resource. Not until the data is brought back and bound to the HTML is it a true "representation". With that in mind, isn't a static HTML page just like any other static content, like an image? Should RESTful URL conventions apply to things like images?
Upvotes: 0
Views: 1388
Reputation: 1809
Having done a hybrid MVC app that handles RESTful URIs and also serves HTML/Json/XML on the same controller, it's a pain. The main issue is what to do when you want to have a creation/edit form. In a normal REST API, the client handles that so you only need a POST /account or PUT /account/123 for the creation itself. If you also handle the client side through MVC, then it's another matter completely.
You can use RESTful principles to help you on the MVC side, but the only totally restful part should be the WebAPI.
If you go the MVC RESTful route, you should not have /account/create or /account/edit at all, per se, as these are actions and you now work with resources. Usually POST = create and PUT = edit (or you can reverse the metaphor... I do prefer the POST = creation when you want to control the IDs generated)
Our solution was to handle the forms themselves as resources:
GET /account-creation-form
fill form and submit
POST /accounts
Redirect GET /accounts/123
=> 123 is the generated id
We had even more issues with this as we needed to pregenerate the IDs on the form before submitting them, which led to asking for a new form with a pregenerated ID and using it to create the account.
POST /account-creation-forms
Redirect GET /account-creation-forms/123
fill form and submit with pregenerated ID 234
POST /accounts
Redirect GET /accounts/234
As you can see, it can quickly get out of hand. Hopefully, most of the app was action based and NOT CRUD. If you have a simple CRUD UI (Create/Edit/Delete), simply use the standard MVC routes and principles, and only make sure the WebAPI part is RESTful, whis will simplify your life greatly.
For example of how to manipulate resources in RESTful ways, to enable/disable accounts:
GET /accounts/123
POST /disabled-accounts?account=/account/123
Redirect GET /disabled-accounts/123
=> /accounts/123 doesn't exist anymore
We are actually moving the resources around based on user action. Same thing you do with files (resources) when you want to copy or backup them.
Still... if you have a WebAPI, do it as REST, but keep the standard CRUD MVC principle if you want to keep you sanity.
Upvotes: 2
Reputation: 19321
In the world of HTTP, you have resources identified by URIs and you have HTTP methods acting on them. You send a request to act on a resource and you get back a response. What is sent in the request (body to be specific) or what got sent in the response body is indicated by the content type. In case of a page, response content type will just be HTML so that a browser can render. So, if you think account page as a resource with URI http://server/account
, you will make a POST to this URI to create a new account. You will make a PUT to the URI http://server/account/123
to update an account with ID 123. Of course, you can use PUT to create a resource but it is slightly off-topic. You will make a DELETE to the same URI to delete it. So, a page or not, any resource can use this convention.
When it comes to implementation, web pages are rendered by browsers. HTML form can have only GET and POST as action. So, in order to do PUT or DELETE, you have to use tricks like using HtmlHelper.HttpMethodOverride
to simulate PUT and DELETE or use XMLHttp (JavaScript) but MVC controller can have action methods corresponding to these HTTP methods. It gets slightly messy because MVC is geared towards RPC-like routing and not HTTP method-based routing like web API.
BTW, thinking the other way, you can have Web API action methods returning HTML. There is no mandate that API should return only JSON or XML.
PS. I'm not sure if I explained this well but one person I know who can do better is Darrel Miller but he has not responded so far and hence I did, just to give my 2c.
EDIT
http://www.bizcoder.com/experiments-with-katana
A few months ago I put up a site http://hypermediaapi.com with the intention of using it as place to aggregate links to all things hypermedia related. I built the site using Web API because a) I know how to use it, and b) I wanted to prove a point that a Web Site is really just a special type of Web API. - See more at: http://www.bizcoder.com/experiments-with-katana#sthash.SQDlVBNf.dpuf
Upvotes: 0