Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API Action return type best practise

From this source: http://www.tutorialsteacher.com/webapi/action-method-return-type-in-web-api I got, that Action in Web API can return:

  1. void
  2. Primitive type or Complex type
  3. HttpResponseMessage
  4. IHttpActionResult

I know what each of this options does, but I am curious whether there is some best practise, for example always use IHttpActionResult as return type, because it is a superset of all other options.

like image 656
MacakM Avatar asked Oct 14 '17 17:10

MacakM


2 Answers

Option 1: Returning void, Primitive type, Complex type

Pros:

  1. Clear from the signature what is the return type.
  2. Unit testing is easier.

Cons:

  1. Not flexible if you want to return a status code if something goes wrong.

Option 2: Returning HttpResponseMessage

Pros:

  1. Flexible to return all items in option 1
  2. Can also return status codes if needed.

Cons:

  1. Not clear from the signature what the return type is.
  2. Unit testing is harder because you have to unwrap it. (not that harder but harder than option 1)
  3. Concerns itself with lower level http status codes and message construction.

Option 3: Returning IHttpActionResult

Web API 2.0 introduced this.

Pros:

  1. All pros of option 2
  2. It does not concern itself with lower level http status codes and message construction.

Cons:

  1. All cons from Option 2 except con 3.

Conclusion

As you can see each option has pros and cons. For me the pros of each option outweigh the cons. My choice is: Option 3. But it is not written in stone.

like image 128
CodingYoshi Avatar answered Sep 22 '22 14:09

CodingYoshi


I use asp.net core but principle is the same. Also, not saying this is the best way, but for me this is the setup that works pretty nice.

I always use IActionResult as its most flexible for me. I can then have action methods completely unaware of DTOs that my services (which action methods call) return. All i do is, more or less, something like this:

[CustomExceptionsFilter]
[CustomValidateModelFilter]
[Authorize(Roles="whatever")]
public IActionResult ActionMethod(params){
  return Ok(this._myService.whatever());
}

This way, if you change DTO that your service returns (which happens alot, especially in early development phases), i don' thave to touch my controller at all.

Also, i have pretty much unified way of returning things where my custom exception error filter catches all service layer custom exceptions like validation exception, operation exception, etc...

[UPDATE]

in filters you don't actually return in a traditional sense. You rather set your context.result (which is of type IActionResult). So, lets say my service throws my custom MyServiceOperationException("You cannot do that") exception.

What i do in my exception filter is:

public override void OnException(ExceptionContext context)
    {
      if (context.Exception is MyServiceOperationException)
      {
        context.Result = new BadRequestObjectResult(new MyErrorResult(){ 
          Message = context.Exception.Message,
          Code=context.Exception.MyErrorCode }
          );
      }
}
like image 20
dee zg Avatar answered Sep 23 '22 14:09

dee zg