Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

We are in the process of constructing an API (using WCF).

So far I noticed 2 ways in which methods could go wrong due to problems with the parameters sent.

  1. wrong format, for example we have a string date parameter which should be in a certain format, if it's in a different format the method cannot continue.
  2. if a method role is to do something identified by an ID, but that ID does not exist in the application (DB)

First we thought throwing an exception, but I realize now that this is not truly an "exceptional" situation, these kind of things is pretty common.

Right now we deal with it in the following way:

We have an abstract class which is called APIResponse. it has a boolean success variable, and an array of messages for the API's client. Each group of methods has a corresponding implementation of this class and that will be the returned object.

is this kind of approach ok?

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

I do like this approach, it is totally acceptable.

Take a look at the Flickr API. They are using error codes and error messages in their api response too.

http://www.flickr.com/services/api/

http://www.flickr.com/services/api/flickr.activity.userComments.html (example api method)

Serving error codes and error messages instead of exceptions is imho much better when dealing with multiple (unknown) client frameworks (.net, java, etc..) If an client api-implementation is wrong because it is using a wrong format, it's much better to display the error message from the server ("Invalid date format. Must be ddMMyyy.") instead of getting an weird "FormatException" (+stacktrace).

Having error ids and error messages:

  • improves api usability
  • improves maintainability
  • improves user / developer experience

API User(Developer) could reference easily to their problem and that will save your time. It would be much easier for you to track down a possible bug/taskswith a specific errorId/errorMessage instead of having "Hey, I'm getting those weird Exceptions when calling XYZ. What am I doing wrong?"

Edit based upon request:

Let's say we have a "BaseResponse" (similar to your APIResponse, comments are stripped out for better readability)

public class BaseResponse
{
  public int ErrorId { get; set; }

  public string ErrorMessage { get; set; }

  public bool Successful { get; set; }
}

And we're having an GetDocumentResponse (implemented by DocumentService, see below)

public sealed class GetDocumentsResponse : BaseResponse
{
   public IList<Document> Documents { get; set; }
}

DocumentService Contract

[ServiceContract]
public interface IDocumentService
{
    [OperationContract]
    [WebInvoke(
         Method = "POST",
         BodyStyle = WebMessageBodyStyle.WrappedRequest,
         ResponseFormat = WebMessageFormat.Json,
         RequestFormat = WebMessageFormat.Json)]
    GetDocumentsResponse GetDocuments(string date);
}

DocumentService Implementation (simplified)

public GetDocumentsResponse GetDocuments(string date)
{
     bool isFormatValid = // parse Date
     if (!isFormatValid)
     {
        // Response = static class, provides generic responses and sets properties of response
        return Response.ProvideFault<GetDocumentsResponse>(100, "The date-format is not valid. Valid: mmddyyyy");
        // return new GetDocumentsResponse { Successful = false, ErrorId: 100, ErrorMessage = "The date-format is not valid. Valid: mmddyyyy"};
     }

     var documents = this.documentRepository.GetDocuments(...)
     return new GetDocumentsResponse { Successful = true, Documents = documents };
}

So, let's say I'm a developer and I want to use this api.

1. - Making an valid api call & getting an valid response from server (JSON Response)

{
   "ErrorId":0,
   "ErrorMessage":null,
   "Successful":true,
   "Documents":[
      {
         "DocumentId":13,
         "Name":"xyz"
      }
   ]
}

2. - Making an invalid api call & getting an invalid response from server

{
   "ErrorId":100,
   "ErrorMessage":"The date-format is invalid. Valid: mmddyyyy",
   "Successful":false,
   "Documents":[

   ]
}

So, for the first call I've done everything right.
The second call says clearly what is wrong, I do not have to research some .NET specific exceptions (or better: wcf faults) if I'm a java developer. In a few seconds after getting the response I do know what went wrong and why it went wrong. I do not have to research documentation or much worse to ask YOU about the current implementation of GetDocuments and why my date format is invalid. It saves you and me a lot of time.

share|improve this answer
    
After looking at the response example (second link) I am not sure as to how the error codes are returned in the response... can you explain a little? –  Mithir Aug 21 '12 at 11:14
    
Sure, I'm making an edit. I'll research an wcf implementation of mine I did a few months ago. The project is now in production. –  lurkerbelow Aug 21 '12 at 11:19
    
This is an amazing answer! thanks. I thought about it a little and it seems like that the successful boolean is not really needed... either you have and error with a message or you don't and its successful... am I right? –  Mithir Aug 21 '12 at 11:59
    
Yes, you're right. It is not really needed, but I do like to have things as "clear" as possible. If you have limited bandwith/resources it should be removed. –  lurkerbelow Aug 21 '12 at 12:08
    
one last thing, have you tried using enums for this? ie ErrorCode... message etc.. ? –  Mithir Aug 22 '12 at 6:30
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.