6

I am currently working on a project which requires data fetching from a 3rd party closed API (over SOAP).

Currently I'm in a situation where I have to do argument and data validation inside our application code, because the mentioned 3rd party API does not return anything relating to errors. Examples:

  1. Request something with a malformed query arg (e.g. 'helloworld' instead of 12345): API returns null, hence not telling me what actually broke the request.

  2. Request with no query args, while the API expects some args: API returns null, so I'm again in the dark about what is going on.

  3. The API can return a collection of data, or a single piece of data. How it handles "no data found": returns null like in all those error cases. This way I do not know whether there actually is nothing to find or whether the API broke again.

I've been trying various things and mapping out what works and what does not. I have got some example request responses from the API provider so at least I know what successful request responses look like.

Are there any good ways to handle situations like these when I just can't ask the API provider to implement proper error handling or similar approaches?

Should I just continue experimenting and wasting time while implementing the validation logic inside our application logic (which should then be abstracted in case the API itself changes or is dumped)?

(I posted this to SE Programmers instead of SO as this is not about a specific technical implementation detail, but about a way of handling the issue in general.)

7
  • 1
    If you depend on the API, the obvious way is to treat every failed request as an internal server error and propagate it to the user. Looks like the creators of said API took the Black box ideology to a whole new level, hiding not only implementation but pretty much everything. Obviously, you can have certain checks in your code, such checks will never allow you to pass a string to a request where a number is expected, but that will not guarantee you compatibility if in the future request with the string is no longer faulty.
    – Andy
    Commented May 6, 2016 at 13:01
  • 2
    In that case I am afraid there's no easy fix. The difficult fix is to force them to implement the desired functionality.
    – Andy
    Commented May 6, 2016 at 13:10
  • 2
    If it's a SOAP API, doesn't the WSDL specify the number and type of parameters each call requires? Can you work backwards from that to do your validation/sanitization?
    – TMN
    Commented May 6, 2016 at 13:25
  • 1
    I've been trying to work that way partly. The one thing that keeps bugging me is that the API returns the exact same response for all errors and empty collections/not found situations (which means I need to magically determine whether the was an error or whether there are no records to fetch).
    – ojrask
    Commented May 6, 2016 at 13:27
  • 3
    Is your organization paying for this? Because if there's money changing hands, then I'd say your organization should be pressuring them for better error handling (at the least they should be differentiating between errors and no-such-data cases). Commented May 6, 2016 at 14:02

2 Answers 2

4

I've implemented and used a "forgiving" API similar to what you're describing. But, it was forgiving only for read-type operations. And the reason was pretty simple: The underlying API (MySQL) was forgiving.

If you connect to a MySQL database, for instance, you might think the only "valid" way to select a record by it's INT PK is to give it an INT:

mysql> select * from users where user_id=123;
Empty set (0.01 sec)

And if you get an empty set you'll just think, "Oh, there are no users with an ID of 123." But, you can also give MySQL a legit string:

mysql> select * from users where user_id='Uncle Bob';
Empty set (0.01 sec)

And MySQL doesn't care. It just says, "Let's see ... oh yeah! None of these integers matches 'Uncle Bob' ... so, that's an Empty set, son."

My API didn't get a validation error from the underlying API, so I never saw the need to "fabricate" one. And, in a way, it makes sense: If you're querying for data that matches malformed or invalid identifiers, the resulting set is just empty.

For read operations, if you want to give the user helpful hints, that's up to you. On the other hand, if the user doesn't already know what goes in the ID field, giving them hints is potentially wasted effort.

For write operations, an API that ignores invalid requests and fails to complain is arguably "broken." But, if that's the case, you could work with the "broken" API by following each PUT with a GET to verify the changes. It's not ideal, of course; but, it should solve the issue.

1
  • Good points! That MySQL analogy does make sense. This API does not allow any writes (for now at least) so perhaps I will just create a test map and see what works and what doesn't when fetching data, combined with Jon Raynor's answer regarding logging.
    – ojrask
    Commented May 9, 2016 at 6:35
4

For this service call, one might want to implement verbose logging.

I assume there is various error handling in place. When an error occurs or null is returned, log everything in the request to and response back. Typically this type of information would go into a debug log, but for this case, I would promote it to your regular logging. Then, you can handle new cases or conditions as they come up.

1
  • I accidentally did this type of logging already as I presumed all null return values meant some type of an error (instead of the API returning null for empty values too). :D
    – ojrask
    Commented May 9, 2016 at 6:37

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