简体   繁体   中英

What is the proper return type for an C# SDK CRUD operations?

I'm currently struggling to write a really good SDK for our API. I'm looking at doing it one of a few ways right now.

  • I can either pass the HttpResponseMessage back from my API call (as you can see below).
  • I can do some data processing and pass back just the object.
  • I can create a custom object to wrap the SDK return so that it can contain what it needs to.
  • I can throw exceptions when a server error is encountered, but that can be expensive especially if the application can recover from the exception.
  • I could also return a tuple in the getter here so that I get both an object and the HttpResponseMessage.

I want the SDK to do just the right amount of processing on the data and I'm not sure if there is an example of how to write a good SDK in .NET or not. I am actually going to consume this SDK myself so I want it to be good. I have written some code and I'll include that here but I think it's current iteration is flawed.

public interface IBaseApi<T>
{
    Task<IEnumerable<T>> GetAllAsync();

    Task<T> GetByIdAsync(int id);

    Task<HttpResponseMessage> InsertAsync(T obj);

    Task<HttpResponseMessage> UpdateAsync(T obj);

    Task<HttpResponseMessage> DeleteAsync(int id);
}

Right now we return a null object to indicate that either Get request failed. But I think that's a flawed concept.

I've also looked at the Facebook, Square, and a few other Sdks. Nothing quite hit the mark for me.

So what return type should my API be sending? Just a pointer, I don't know how the client is going to consume this. It could be part of a larger query or a direct pass through to their Controller. My overall goal is that the consumer will have as little processing to do themselves, but also a meaningful if something goes wrong message.

What I have done in the past and has worked really well is to create an "Api Response" object that contains metadata about the response as well as the actual data resulting from the call, something along the lines of:

public class ApiResponse<TData>
{        
    /// <summary>
    /// Constructor for success.
    /// </summary>
    /// <param name="data"></param>
    public ApiResponse(TData data)
    {
        Data = data;
        Success = true;
        Errors = new List<string>();
    }

    /// <summary>
    /// Constructor for failure.
    /// </summary>
    /// <param name="ex"></param>
    public ApiResponse(IEnumerable<string> errors)
    {
        Errors = errors;
        Success = false;
    }

    /// <summary>
    /// Gets whether the API call was successful.
    /// </summary>
    public bool Success { get; private set; }

    /// <summary>
    /// Gets any errors encountered if the call was not successful.
    /// </summary>
    public IEnumerable<string> Errors { get; private set; }        

    /// <summary>
    /// Gets the data resulting from the API call.
    /// </summary>
    public TData Data { get; private set; }
}

You could have a base class that does not return any data too and then derive this one from that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM