0

My team needs to design an API which sends objects to a queue in the cloud and retrieves objects from it. The data is inserted into the queue as byte[].

We have 2 ideas until now which I would love to hear your notes/ideas about them:

First version:

  • public void push(String object)
  • public String retrieve()

Notes: To support this API, any consumer must implement a logic to convert his objects to Strings and vice versa.

Advantages:

  1. Easy to implement.
  2. Easy to maintain.

Disadvantages:

  1. The consumer of our API must design a solution which is not related to his logic for converting his objects to Strings.
  2. The consumer of our API must call a method which converts his objects by himself even though it is not related to his logic.

Second version:

  • public void <T> push(T object)
  • public T <T> retrieve(Class<T> type)

Advantages:

  1. Easy to implement. (In Java, we can use ObjectMapper)
  2. Easy to use this API.
  3. The consumer of our API does not need to manually convert his objects to anything else.

Disadvantages:

  1. The types of the consumer of our API must support Json converts - recursively, a class with object properties, all property types must support Json converts.
  2. If the consumer does not read the documentation carefully, something won't work or there will be a silent bug.

General notes:

  1. The API needs to be supported for at least 4 years.
2
  • 1
    If the consumer does not read the documentation carefully, something won't work or there will be a silent bug.Like anything else in this crazy world. – Laiv Feb 19 '18 at 10:08
  • Please think about 'syntax' and 'semantic' and ask yourself what is the semantic of your API. This should be clear for all users of your API. – Tobias Otto Feb 20 '18 at 14:18
2

There is a potentially major overlooked disadvantage with the second approach, and that is if the class changes from the time in which it was inserted to the time in which it was retrieved, deserialization will fail.

You could throw a proper exception to make the error clear, but you also wouldn't be able to do anything about it. The caller would know the error clearly, but the caller himself wouldn't be able to do anything about it, having only the most recent version of the class. In order to use that interface, after any change to the class, there must be a converter class that retrieves all old instances of that class, destroys that instance on the cloud, then recreates it using the new version of the class.

This is no small feat. If you want to take this approach, you may want to consider having an upgrade possibility which does this on behalf of the caller.

Your first solution, despite being somewhat inconvenient, is more robust. It isn't likely going to fail, which may be important. You can have both options if you wish, nothing is stopping you from doing so, leaving it up to the caller which to use. At least in the case where an older version is saved, there exists the option of retrieving the string value of the failed deserialization to deal with at a later moment.

3

I would do the second option but allow the user to inject their own serialiser/deserialiser.

Throw exceptions when the serialisation fails to avoid your silent failure problem.

Given that you are persisting as a byte[] it might be best to serialise to one to avoid character set problems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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