Kavya Shetty
Kavya Shetty

Reputation: 315

c# REST API polymorphic return type

I have created data contracts as below having inheritance:-

[DataContract(Name = "Animal")]
public class Animal { ... }

[DataContract(Name = "Dog ")]
public class Dog : Animal { // Has some Dog specific member properties }

[DataContract(Name = "Cat ")]
public class Cat : Animal { // Has some Cat specific member properties }

And I'm using ASP.NET WebApi to provide a REST API like:

[HttpGet]
public Task<Animal> Get(string type) 
{ 
    switch(type)
    {
        case "dog":
            Dog dog = GetDogDetails();
            return Task.FromResult(dog);
            break;

        case "cat":
            Cat cat = GetCatDetails();
            return Task.FromResult(cat);
            break:
    }
}

I am not able to return the respective animal types. I get the following error:- "Cannot implicitly convert Dog to Animal".

Also is this polymorphic response a good thing as per REST API standards.

Upvotes: 3

Views: 2306

Answers (1)

Vlad Stryapko
Vlad Stryapko

Reputation: 1057

The reason you get this error is because you're returning a Task<T> and task is not covariant. That is, even though Dog is Animal, Task<Dog> is not Task<Animal>.

What can you do?

  1. Change your code to be

        case "dog":
        Animal dog = GetDogDetails();
        return Task.FromResult(dog);
        break;
    

You will lose dog's specific properties though.

  1. Leverage Task<IHttpActionResult> and return Ok(yourObject).

    [HttpGet]
    public async Task<IHttpActionResult> Get(string type) 
    { 
        switch(type)
        {
            case "dog":
                Dog dog = GetDogDetails();
                return Ok(dog);
                break;
    
        ...
        }
    }
    

I think you should go the second way.

On a second note, I don't really see any reason to use async/await here. Why would you use Task.FromResult? If your GetDogDetails method is async, consider awaiting it. I don't think you should worry about Tasks in your current code.

Also is this polymorphic response a good thing as per REST API standards.

I don't know about formal standards but in general it's OK for some objects to have certain properties and for others not to. For instance, imagine a payment system which returns an abstract Event which might or might not have an associated invoice with it.

Upvotes: 6

Related Questions