Hard agree with the YAGNI conclusion. There's a certain minimal amount of complexity needed to build your system, you need a good reason to build out another layer of indirection / abstraction here, something like needing web + mobile for the MVP or offering users direct access to the API as part of the MVP. Remember: if you think there's value in a REST-style layer, you don't need to build a separate API to support that. You can just write a getUsers() method on the server instead.
What do you get when you throw out the API layer? Easier refactoring (no wondering who all the consumers of GET /users are). No implicit contract with users who have reverse-engineered your API (and complain if you break it). Easier security (who needs API tokens?). No organizational footgun that leads to a frontend/backend team split and then requires a group manager to get new features shipped, because of course your API doesn't actually expose feature-specific data for features that Product hasn't dreamed up yet.
Sure, if you're FAANG scale, it'll be easier to work with APIs. You'll have some Staff+ Engineer architecting everything and coordinating between Product and a half-dozen teams that'll take months if not years to ship, and everyone will be happy with that. Strong fences make good neighbors, and contracts keep teams independent of each other. But in the early days? Feel free to ship things that don't scale.
I beat the drum of complexity vs complication. Solutions to a given problem have an inherent complexity. That’s the minimum amount of sophistication and cleverness required to implement them. And then there’s complications (think of the watchmaker’s term) which extra features that don’t directly solve the problem but, well, they look kinda neat!
Strive to find that inherent, irreducible complexity and solve at that level. Resist the urge to say “for just 20% more effort…”
I think your comment doesn't really make sense. Unless you're somehow assuming that the one and only way to do web apps is to go the dynamic html path, I don't see how your suggestion can even apply. Once you have a frontend that needs to retrieve data from a backend, how do you even address that?
Your comment reads as if someone complains people don't actually need cars because they can just show up somewhere.
If you use an API, but in a way the author suggests (conformed to the UI, rather than an abstraction), what's the simpler/better way to do auth than API tokens?
I have depth of experience in a niche industry and I'm working to build solutions for that industry, but I'm still early on the learning curve of being an effective full stack developer to make those solutions.
> Easier refactoring (no wondering who all the consumers of GET /users are)
Unless your API calls are properly abstracted into function calls. No reason you can't just have a `getUsers()` function on the frontend, and then use your favorite “find all references” tool from there.
What do you get when you throw out the API layer? Easier refactoring (no wondering who all the consumers of GET /users are). No implicit contract with users who have reverse-engineered your API (and complain if you break it). Easier security (who needs API tokens?). No organizational footgun that leads to a frontend/backend team split and then requires a group manager to get new features shipped, because of course your API doesn't actually expose feature-specific data for features that Product hasn't dreamed up yet.
Sure, if you're FAANG scale, it'll be easier to work with APIs. You'll have some Staff+ Engineer architecting everything and coordinating between Product and a half-dozen teams that'll take months if not years to ship, and everyone will be happy with that. Strong fences make good neighbors, and contracts keep teams independent of each other. But in the early days? Feel free to ship things that don't scale.