MortenGR
MortenGR

Reputation: 833

How to design a class containing the result from a webservice

Problem I call different webservices which returns json strings. I parse these strings to custom objects and save them in a "result class" called APIResult. For instance, one webservice returns a list OBJ1, another returns OBJ2, and sometimes two or more objects are returned as well. The result class is returned to the method calling it with the objects and a boolean indicating whether the request was succesful.

This works, but when I have to call many different webservices the class gets ugly. Right now I have 7 properties like OBJ1, OBJ2, List, List and so on. To avoid adding more properties to the APIResult class I want to redesign it to be more flexible, but I'm not sure what is the best approach.

Ideas Generics seems to be a good idea. I could initialize my class with new APIResult(ObjectType) and then have one or more properties T Data1. Still a bit ugly to have three properties T Data1, T Data2, T Data3. I am also unsure if I can parse the objects from json to a generic type without reflection and if that would slow things down.

Do you have any suggestions?

Upvotes: 4

Views: 756

Answers (2)

theDmi
theDmi

Reputation: 18034

Separate the result state from the actual data.

As you suggested, generics are a useful tool for this. Create a result state class that encapsulates the success/failure logic and (in the case of success) provides access to the data.

This could look something like this:

public class ApiResult<T>
{
    public bool Success { get; }

    public T Dto { get; }

    public ApiResult(bool success, T dto)
    {
        Success = success;
        Dto = dto;
    }
}

Now design the data classes as simple property bags without any logic. Their only purpose is to define what data is returned from a specific web service. Also, do not try to build deep inheritance hierarchies. Adding the same property to two different DTOs is fine.

public class Dto1  
{
    string PropertyA { get; set; }
    string PropertyB { get; set; }
}

public class Dto2  
{
    string PropertyA { get; set; }
    string PropertyC { get; set; }
}

With this, you are now able to define proxies for the web services you call. A proxy interface could look like this:

public interface ISomeServiceProxy
{
    ApiResult<Dto1> GetTheThing(string someParam);
}

In the implementation of this interface you will want to use JSON.NET to deserialize the response into a Dto1 and wrap it in a ApiResult.

Also, you probably want to make the proxy use async. I left that out in these examples, converting them is straight-forward.

Upvotes: 3

Batavia
Batavia

Reputation: 2497

There are few things to consider here

  • Do you need an APIResult class? What are you going to do with it? If you have a well documented REST api (say an odata api) then the response is well described and you can verify that the response you get is what you need. Otherwise what are you going to do if it doesn't match?

  • if you are just going to parse it into your model you might even consider the generic JObject to hold your response. Then you can check for properties/subobjects on this JObject. You could even pass this into the (newtonsoft) json serializer and have the calling method say what it should look like.

  • what is the business meaning of your response? Result is always a hard name. However if you you have properties like FirstName, LastName, AddressList, etc then it becomes a lot nicer.

Upvotes: 0

Related Questions