For the purposes of providing a concrete example for my question, let's say I'm building an API that provides access to an email system and contains a set of public classes e.g. Mailbox, MailboxFolder, Message, MessageAttachment, and so on.

Is it a good idea to try to anticipate how clients may use the API and provide "helper" methods for common operations?

For example, imagine my Message class has a Save(string toFilePath) method. Maybe it would be helpful to provide another method in Message that builds a "safe file name" from the subject of the message, i.e. a file name that is some reasonable portion of the subject (since the length of an email subject can far exceed the maximum length of a file path) where all characters that are not valid for use in a file name have been replaced with a usable character.

The reason for this would be that I anticipate clients may often want to save an email with a name that resembles the subject.

  • Its helpful, but I think you are stretching the definition of API – Ewan Oct 8 '15 at 16:19

"Safe file name builder" is not something I'd expect (or even want) to see in an email-related library. Building a "safe" string from arbitrary message subject can be a rather complicated task if you think about encoding, allowed characters for paths in different OSs, etc., so it's better be handled by specialized API/library.

General principles are:

  1. Assume less, make your API as agnostic to it's "environment" as possible. Imagine that your API can be used in a browser, which can't even save a file, so it wouldn't even need the Save method. It would be better to provide some form of serialization instead of Save method and let users decide how to handle serialized massages: print, save to files, transfer over a network, etc.
  2. Don't clutter your API with stuff your users can only possibly need - see scope creep and YAGNI
  3. Respect the single responsibility principle. Choosing a name for a file is not something that email message should do or even be aware about.

As for helper methods which don't violate the principles mentioned above: if you choose to put such methods to appropriate classes, it's fine.

| improve this answer | |

No, absolutely not!

In general, you should never "anticipate". Predictions are hard, especially those concerning the future. APIs should be extracted from working code, not pulled out of thin air. Follow YAGNI, follow the Rule of Three (don't extract an API until you have three independent clients).

In this particular case, even if you had three clients, a file name sanitizing API has no business being in an email library. It belongs in a file name library.

| improve this answer | |
  • BTW: I wrote this hours ago, when there was no answer yet, but somehow, it didn't get sent. Feel free to ignore this, and definitely upvote the other answer. – Jörg W Mittag Oct 8 '15 at 21:04
  • Your answer is great too. – rory.ap Oct 8 '15 at 21:07
  • Thanks. I was thinking about the "generic VCS plugin API" in Eclipse, which was created, when there was only one single VCS plugin for Eclipse (CVS), and, as it turned out, only worked for CVS and Subversion (which being developed by former CVS developers specifically as a replacement for CVS with a minimal learning curve, had very similar semantics), and was extremely painful for "checkout-style" VCSs such as Perforce and VSS, and distributed VCSs such as Git and Mercurial. Similarly, the VCS API in Visual Studio, which couldn't even be used by Microsoft itself for TFS, and was changed. – Jörg W Mittag Oct 8 '15 at 21:12

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.