7

So I've seen the Web API 2 Controllers return HttpResponse and the actual object. Example:

 public HttpResponseMessage Get(string id)
    {
        var app = apps.Single(c => c.Id == id);

        return new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new ObjectContent<object>(app,
                Configuration.Formatters.JsonFormatter)
        };
    }

or

 public Application Get(string id)
    {
        return apps.Single(c => c.Id == id);
    }

My question which is the 'right' way? #2 is much shorter but is it better to do #1 or does #2 do #1 automatically ... ?

amcdnl
  • 8,470
  • 12
  • 63
  • 99

1 Answers1

13

See this and this SO questions.

The response will be the same (HttpResponseMessage) in both cases.

HttpResponseMessage allows you to work with HTTP protocol (e.g., via Headers property) and unifies your return type.

Returning CLR types can be more readable, but you loose flexibility to return different types with different status codes unless you use dynamic or object which defeats the purpose of returning a specific type.

Personally, I prefer to use IHttpActionResult (added in v2) and to specify a ResponseTypeAttribute on controller actions for the expected return type to improve readability.

[HttpGet]
[ResponseType(typeof(Portfolio))]
public IHttpActionResult GetPortfolio([FromUri] long id)
{
    // get portfolio

    return Ok(portfolio);
}

You can easily manipulate response messages (in a RESTful way) using default IHttpActionResult implementations (see OkResult above). Avoiding constructing HttpResponseMessage yourself also keeps code clean. Here is an official article on IHttpActionResult and here is an interesting SO conversation on HttpResponseMessage vs IHttpActionResult.

Community
  • 1
  • 1
Nikolai Samteladze
  • 7,699
  • 6
  • 44
  • 70
  • Arguably, you don't WANT to allow the flexibility of returning different types; that just obfuscates the intent of the service and makes it less self-documenting. IMO, less code is better given two methods resulting in the exact same output. Plus, you could always switch to returning HttpResponseMessage if and when you NEED to work with the HTTP protocol. Otherwise, the HttpResponseMessage approach just adds clutter. – Colin Dec 31 '15 at 17:54
  • Self-documenting API arguments makes sense, but you can use `[ResponseType]` attribute to signal API response type to external docs like Swagger. I, personally, like the fluency of `return BadRequest()` compared to `Request.CreateErrorResponse`. Also, `IHttpActionResult` implementation can do more than just returning a value (e.g. add headers, log messages, etc.) – Nikolai Samteladze Dec 31 '15 at 19:41