📜 ⬆️ ⬇️

Keep API simple

I want to tell about one case when we managed to come up with a simple API, when at first the task seemed complicated.


We recently received a task. We had to log every user action that he can perform on our website. In other words, we needed to create a class (API) that could easily be used in almost all controllers in our system. Difficulties added the fact that, depending on the action need to log various additional parameters.

Together with this task, we got a half-finished solution made by some developers.

')

First decision


We will not now consider how logging is done inside - it is interesting for us to see how convenient it is to use it outside (that is, just the API). Here is what a typical controller code looked like in which you need to log a user action:
private void logUserAction(User user) throws Exception { UserActionModel model = new UserActionModel(); model.setAction("Buy a ticket"); List<String> values = new ArrayList<String>(); values.add("PersonCode"); values.add("UserName"); values.add("ContactInformation.EmailAddress"); values.add("ContactInformation.Language"); model.setParams(LogUtil.getParamsWithFieldNames(user, values)); LogUtil.log(model); } 


Probably, it is obvious how LogUtil.getParamsWithFieldNames works. After receiving the “user” object and the list of strings, it calls the appropriate getters: user.getPersonCode (), user.getUserName (), etc.

Lovely


Well, gracefully?
See what a thoughtful, versatile solution! It does not depend on a particular class, be it User, Client, Customer or something else. Just feed this object and the list of strings to the LogUtil class, and it will add all these values ​​to the log itself. Oh yes, this is a smart API!

But


Only you know what? You need this intelligence, like a dog's fifth leg!
Stop for a second and think: is it possible to make it easier? Sure you may!

That's why we need to use reflection here? Why lose the advantage that the compiler gives - he can immediately find the error if you suddenly made a mistake in writing the getter? Why bother with exception handling? Why not just use getters?

And yes


As a result, the solution was easier, shorter and more reliable. Here is what the typical controller code now looks like:
  Action action = new Action("Buy a ticket") .add("PersonCode", user.getPersonCode()) .add("PersonName", user.getPersonName()) .add("EmailAddress", user.getContactInformation().getEmailAddress()) .add("Language", user.getContactInformation().getLanguage()); LogUtil.log(action); 




Like this. As simple as possible.
As bequeathed old Einstein .

Source: https://habr.com/ru/post/117199/


All Articles