1

What we often see is that software companies create an internal API which is then consumed by their own user interface. And we were trying to find the benefits of those, other than it's easy/easier to switch to another technology for user interface. Mostly these API's are custom made for that specific UI and isn't generic in any way. Talking about monolithic applications.

As in, you cannot expose a subset of calls of this internal API to a third party.. or use the same internal API for a mobile app. Because most of the time it isn't generic, especially in very complex applications.

So really what is the benefit of this approach over e.g. creating am application which directly talks to the services instead of going through an API first and maybe add an extra API for third parties (which have totally different calls but work with the same app code)

1
  • 2
    Seems to me your question could be summarised as "don't build bad APIs, build good ones instead". Mar 9 at 10:45

3 Answers 3

2

There is none.

There is no benefit from creating an "API", i.e. an intentional boundary, inside the same application. In fact, there is a huge downside, because now a lot of changes will have to go through this "API". Meaning a lot of changes will not be localized.

The typical "just add a field on the UI" type requirements taking multiple days to implement. I've built tons of these unmaintainable applications back in the day with Java Enterprise. I'm not proud, just saying. :)

The mere fact, that you require some kind of reasoning already shows you're much more competent that those projects that do this (introduce APIs) basically without thinking at all, just because it is "in" these days.

3
  • Thanks for these thoughtful insights. I agree with the fact of "just add a field on the UI" gets overly complex. How would you tackle the upcoming issue when they ask for a 3rd party API or a mobile app API (only a small subset of calls). Would you just add an API for every of those occasions?
    – Jesse
    Mar 9 at 12:41
  • Additionally, when using a SPA framework like React or Vue for the UI. You almost certainly need an API so the SPA can interact with the backend. In a C# or Java world you can of course use WPF, UWP or any other UI which directly uses the backend code without an API in between.
    – Jesse
    Mar 9 at 12:43
  • 1
    I wouldn't do SPAs. It is rarely, if ever, worth it. You can easily do fancy/responsive stuff without building the UI separately. Apache Wicket is something I've used for this for example, there are many others. If you need 3rd party or mobile APIs it's different. You'll need some sort of trade-off and I don't have a generic solution. I would look at how extensive those need to be, what possible options I would have. Point is, even then, weight everything! APIs are hard to maintain, they're a cost, so find real reasons make decisions, even case-by-case basis if need be. Mar 9 at 13:26
2

There are two benefits of using an internal API to support the UI.

  • Replaceable UI
  • Testable API

Of the two, testing is the most common benefit. People talk about swapping out UIs but it’s rare for a project to maintain two UIs. But UIs are always hard to test compared to APIs.

That’s why we have the Humble Object Pattern. It tells us to move logic from things that are hard to test to things that are easy to test. Therefore you move all interesting code out of the UI and put it in something with an easy to test API.

The fact that this also makes your UI easy to swap is nice. But rarely the point.

Well, unless you consider a test suite a UI. If so you’re replacing the UI all the time.

But just adding one field is so hard!

If that’s a common problem change the design so you’re not hard coding the fields. Neither the UI nor the API need to know the names of every field.

Is this better than talking to the services? Well if talking to the services requires you to keep interesting logic in the UI then yes this is better. Interesting logic should live in something easy to test. If not, well the services already have an API don’t they?

1
  • 1
    I understand your point but in the C# world, Jimmy Bogard, introduced the Vertical Slice Architecture. He even has an example online in GitHub where the code is all together (no API) but the code is still testable because he is using CQRS. So testing can be done without an API as well.
    – Jesse
    Mar 9 at 14:42
1

If I understand your question correctly, the main benefit of doing this is (if it's done well) it decouples your UI from the services. A secondary benefit is potentially simplifying client interactions. API is a term that can be used to describe the service interface as well so I'll refer to the API in your question as a wrapper library.

You mention that it makes it easier to switch to a different interface which is true but I think it's actually the ability to change the services without forcing work on the client team. For example, let's say you have an old SOAP API and you want to move to REST. If your user interface is calling the SOAP services directly, then the client team will need to modify their code in order to do this. If you client only depends on a wrapper library, you can have the service team make do all the work and deliver a wrapper library that is backwards compatible. In the somewhat unusual case that you have more than one set of services or sources, this could be a highly effective way to interact with them using a single UI. An example of this is something like DBeaver which can work with many different database. Internally, I would wager they have a single 'canonical' API that is DB agnostic, at least to some level.

Another reason is that you might have multiple clients. For example, you might have a GUI, a CLI, and server-side background processes that all use the same service layer. Now, when you make a change to the services, the ability to provide backwards compatibility through your wrapper library becomes more valuable, if (and it's a big 'if') all your client applications are able to use it. This tends to not be the case in my experience.

The above applies to 'generic' interfaces. You say these are not which would tend to lead me to Robert's answer.

The other potential benefit is that you might be able to simplify and/or optimize the client interactions. Say you have a REST API where you have to first retrieve a list of resources and then retrieve each of those resources. A client wrapper could accomplish that in a single function and produce a list or stream of deserialized objects/structures. Depending on the skillsets of the client team, this could help them focus on the UI work.

I would expect the wrapper library to be managed by the team building the services. Updating the library should be part of making any change to the services.

Now if this is a purely client-side library managed by the client team, it could be used reduce duplication in the client or simplify the interactions as discussed before. But if this API is an isomorphic pass-though, then it's likely pointless and could just be inertial.

4
  • You understood my question very well, thanks! However, what if your API exists of more than 200 calls.. just because the complexity of the application. A team before me did a failed attempt at creating a some sort of REST API for the application. Yes it worked but it was just so big because of all the features in the application. We're not talking about 10 calls but over 200 calls. The wrapper idea sounds nice, but again not for this size of project, in my opinion.
    – Jesse
    Mar 10 at 8:42
  • Also the comment on when you have multiple clients (GUI, CLI, server background processes).. I feel like they never really need EXACTLY the same code in the service.. but just a slight variation of it or completely different implementations. That's why it feels wrong to write a generic API which is then used by a CLI, GUI and server process. Because the server process might have specific things to do, which the CLI and GUI don't need. Maybe we need another GUI with a small subset of information without the other data to be exposed..
    – Jesse
    Mar 10 at 8:44
  • 1
    I feel like you are looking for someone to tell you whether the specific solution you are working with makes sense. It's really hard for you to give enough detail to get a meaningful answer and it wouldn't be very useful for anyone else. Instead, I'm telling you all the reasons that this might be useful that I can think of. If none of these reasons apply to your situation, then perhaps the wrapper library is not worth the efforts. I think the number of operations is more-or-less neutral to the decision.
    – JimmyJames
    Mar 10 at 14:23
  • 1
    "I feel like they never really need EXACTLY the same code in the service" So I wouldn't expect the wrapper library to implement the client application logic for the reasons you mention. That isn't really one of the reasons I would do this. The fact that applications might need different subsets isn't a problem. The library wrapper supports the superset of functionality, just like the services. The library wrapper should be considered part of the services, not the client.
    – JimmyJames
    Mar 10 at 14:34

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