1

As far as I understand the ApiController is for performing CRUD on resources.. But I have a case where I am just calling some Helper method (Restoring a DB on a SQL server) and so I am not sure if ApiController makes sense ?

Should I only use ApiController when I am performing CRUD on something ? Or should I use ApiController for anything that does not return a view ? Is 'post' the correct HTTP verb to use ? Am I going about this all wrong ?

Id like to get it clear in my head when to use one over the other.

   [HttpPost]
    public JsonResult RestoreBaselineDB()
    {
        //Get values from web.config
        string sqlServer = ConfigurationManager.AppSettings["DBTools_sqlServer"];
        string backupFilePath = ConfigurationManager.AppSettings["DBTools_backupFilePath"];
        string destinationDatabaseName = ConfigurationManager.AppSettings["DBTools_destinationDatabaseName"];

        DatabaseHelper.RestoreDatabase(sqlServer,
                                       backupFilePath,
                                       destinationDatabaseName,
                                       "c:\\temp",
                                       "ProcessManager",
                                       "ProcessManager_log");

        return Json(new
        {
            Status = "OK",
        }, JsonRequestBehavior.AllowGet);
    }
1
  • so one person says use controller.. The other says apicontroller.. Though I like the idea of just rethinking what I am doing in terms of REST.. the restore of a database can have values associated with it.. I possibly use GET to check status.. the POST would change the object (that is.. restore a database.. set any status related flags) Commented Sep 20, 2013 at 15:00

2 Answers 2

3

Controller is the base class for MVC, and ApiController for web api, which can be intermixed but should have clear, distinct purposes. I would use ApiController if you intend to create a restful web service, and Controller for your web application's user interface. I wouldn't necessarily intermix the two, based on the function you are creating.

For instance, if you are creating a REST service for an API your are exposing to the world or your application, keep everything contained in a web api set of APIControllers. But consider using a Controller for returning JSON to a view in a utility scenario.

This is, of course, subjective and likely to have differing opinions.

Sign up to request clarification or add additional context in comments.

Comments

2

As @Brian Mains recommends, in your situation, you should use an ApiController because, as you say, it does not return a view. Controller should be used for your UI.

The answer to your question about is ApiController just for CRUD takes you dangerously close to the REST flame wars.

A pure REST approach to this would be to think of your restore database operation as creating a DatabaseRestoreRequest resource (and therefore should be a POST).

POST <Host>/Api/DatabaseRestoreRequest

Since the restore is probably a lengthy operation (especially for large databases), the body of the POST response would represent a resource with a unique identifier and a status that could be one of

  • InProgress
  • Failed
  • Complete

Having done a POST to initiate the restore (status would be InProgress), you would then make a GET request, providing the unique identifier. The GET response would give the updated status. You could call GET repeatedly until the response had a status of Complete.

GET <Host>/Api/DatabaseRestoreRequest/<requestID>

You may also have a DELETE operation, which could cancel the restore operation.

DELETE <Host>/Api/DatabaseRestoreRequest/<requestID>

If this seems over complicated and unnatural to you, you could just use a pattern like that used by the Windows Azure management API (and others). This uses a URI scheme that indicates a resource in the main URI and then the operation as a query string parameter

For example, to re-image a virtual machine you would do a POST to

https://management.core.windows.net/<subscription-id>/services/hostedservices/<cloudservice-name>/deploymentslots/<deployment-slot>/roleinstances/<role-instance-name>?comp=reimage 

In your case it could be something like

POST <Host>/Api/Database?comp=restore

POST is traditionally used for this kind of operation because they are often non-idempotent. Idempotent means that if you repeat it several times it has the same effect as if you do it just once). PUT is supposed to be idempotent. POST does not have to be. This comes from the W3C:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

REST purists might decide to flame and downvote me for suggesting the second option. But hey...

2 Comments

I see.. So rather than create a new apiController for every type of database utility class I can create one ApiController that except a 'method' as a parameter right ? and other parameters could be on the query string.. though now it starts to feel like it would be more natural as a WCF service with parameters? Though I don't wanna go there anymore and rather just make everything REST
It does feel like a WCF/SOAP service. But sometimes, that is just the way it is, especially for existing systems that are not designed in a "resource-oriented" way. In general, I think I would try to do the pure REST approach, unless it feels like you're bending over backwards. And I wouldn't necessarily put all your utility methods in one controller - still pay attention to good OOD and separation of concerns.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.