Pregunta

This question is highly related to this over question. I'm asking another question between I still am a bit confused on the topic.

The Issue I Ran Into

I currently have a Django web application where users can have a list of their hobbies and can increment a counter each time they do one of their hobbies. My issue is, I want to extend this functionality outside of a front-end experience. In other words, I want users to be able to increment their hobbies using a POST request, say, from the terminal or from their own script or something.

Where I'm Confused

Do I have to create an API for my webapp to add this functionality?

Another way to put is, do I have to handle requests coming from the front-end differently than requests coming from somewhere else? Would front-end requests go to the URL www.hostname.com/hobbies/1 and other requests go to the URL www.hostname.com/api/hobbies/1?

If I do route the POST requests to the same URL as the requests coming from the front end (i.e. www.hostname.com/hobbies/1), then how come google has external APIs for Google Maps? It seems like if other web applications are calling Google Maps functionality then Google has separated those instances from their front end.

¿Fue útil?

Solución

In the expected form of Interactions

And that depends on the user. To a user that understands web APIs and programming, sending a POST to /hobbies/{name}/increment is similarly intuitive to clicking a button in a UI. Even more, to such a user the API may be much more comfortable because it is magnitudes easier to integrate into other automations. However, to a user that has no idea what a POST Request could be, the UI is the only viable option.

So, when creating your Application you have to decide what users you want to appeal to and implement the necessary interfaces. This decision is mostly a business decision, and only a technical one when it comes to doability and effort.

Dealing with changes and Maintenance

Things get more nuanced when it comes to changes to the functionalities you provide. The key term here is backwards compatibility.

Whenever you want to change a functionality your users must be aware and be able to adapt to the change. Here, a UI is magnitudes easier to change; a UI is used by humans exclusively and due to this, the UI can rely on human levels of intelligence for adaption to a changed interface. Humans notice when there is a new input field or when there are other options to choose from in a radio-button group. And they can adapt to a certain degree. This is really the realm of UX, not software engineering. The important bit is: a UI is much easier to change and fix.

A script written against APIs has an adaptability of exactly 0. If you change an endpoint in your server code, scripts that cannot handle the change will do all kinds of weird things; crashing loudly is only the best case. Further: when you have a change to make, changing the UI code doesn't suffice. You'll also have to change server code so the UI can pass the task on to the server correctly. And this is the fundamental issue.

It all comes down to the promises you made to your users. If you promise a stable Web API suitable for complex automations, it better be stable. You need a separate Developer-to-developer channel for upcoming changes, too. Now, surely you can delay your UI changes until all your API customers/users are ready for the change. But that slows your UI development to a crawl or less.

All of that is why most larger apps have two APIs that are similar: one for the internal clients (UI code, but also others) and a stable API for external users. The internal endpoints can change fast because there are only few clients and all of them are under the same governance as the API.

Note that this doesn't mean you should duplicate your API code. You can serve /hobbies/1 and /api/hobbies/1 with the exact same code in your backend. The difference is where the inflexible clients connect: to the /api/* endpoints. When you want to change the /hobbies/1 semantics, you can leave the old code/semantics in place for /api/hobbies/1 and route calls to /hobbies/1 to the new code/semantics.

Licenciado bajo: CC-BY-SA con atribución
scroll top