> Imagine if you could just send it the whole “page” worth of JSON. Make an endpoint for /page/a and render the whole JSON for /page/a there. Do this for every page. Don’t force your front-end developers to send a bunch of individual requests to render a complex page. Stop annoying them with contrived limitations. Align yourselves.<p>Why not just send HTML as a single response at this stage? Sometimes it feels like we are doing web development more complex than it needs to be.
One extra thing I have confirmed after writing this article: it's usually a bad idea to reuse back-end data in multiple places on the front-end.<p>If you think about functions or object constructors in general, it kind of makes sense. One of the most important architectural practices I've ever discovered is: don't pass in the parameters that you have, pass in the parameters that the function needs. So if you have companyName, and you are constructing a page that has a title, you shouldn't pass it companyName: companyName, you should pass it pageTitle: companyName (parameter name: parameter value). It's crucial that the parameter is named after what is needed, not what you have. This is kind of the essence of what the article is suggesting.<p>If your front-end is reusing a lot of fields from back-end, it's likely that you're passing it what you have in your database/resources, and not what it needs — fields for constructing the UI, configuring the views. Moreover, I rarely see front-end going through the exercise of defining exactly what they need. The article encourages more of that.<p>Once the front-end starts reusing the generic back-end fields everywhere, you lose track of your use-cases. Everything you ship from the back-end becomes potentially important for mysterious reasons that not even front-end can easily understand anymore. Front-end already built complex dependency trees based on these generic fields. If you actually untangle these trees, it might turn out that your front-end can only exist in 5 different "modes", but you can no longer see that in the tangled mess. You can no longer streamline and optimize these 5 configurations.<p>So to summarize: pass what is needed, not what you have is a good general architectural rule that's also applicable between back-end and front-end.
Gotta say I disagree with this idea. RESTful APIs have become the norm for a reason, and in my opinion it's dangerous and damaging to suggest abandoning them for a whole swathe of back-ends.<p>Re: YAGNI. I worked on a product where, about 10 years ago, they decided to build proper APIs (for the first time), mainly to power their own front-end, but they also told the paying clients that they were welcome to use them. Didn't take some clients long to start using and loving those APIs. (Granted, they were enterprise clients, with their own significant dev resources, that's not the case for all software.)<p>Re: front-end doesn't really have freedom. Yes it does! If one day page A needs a list of X, and there's already a nice generic API endpoint to list X, then only a front-end code change is needed.
This article is good advice to get a working prototype or a decent solo-dev MVP website that will be re-written later. I've spent the last two months cleaning up the work of a developer who thought this way. Here's what you run into:<p>* Front end and back end become conflated. Often times code that should run on the backend runs on the front end and vice versa. Often shortcuts like saving ui state using the same api endpoint you use to save data become complex, and slow down improvements to both the ui and the public API. Likewise data manipulation and in some cases even validation gets done on the wrong end, too.<p>* You confuse UI code with application functionality. Code used to save the order of columns, stuff you entered the last time a dialog was displayed, and the convenient data structures (i.e. easy, not best) for the front end leak into the back end. So you end up spending a lot of time building back end functionality that has literally no utility to anyone else other than the front end developer.<p>* You lose focus on your other users: developers who integrate and build on your product. Eventually, those developers become in-house people who are doing integrations and implementations for customers, and a messy API will really slow them down.<p>Better advice: separate the concerns and have a separate API UI backend. Build exactly what you need to deal with UI state, and component specific UI settings. Your front end team is a perfect proxy for a third party developer for your public API. Take advantage of that. If they can't use it, or they get paper cuts, then paying customers will have problems, too. You'll also be able to on-board developers faster (easier training) and have better documentation.
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.<p>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.<p>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 <i>early days</i>? Feel free to ship things that don't scale.
My personal take: Don't put it all in the same box.<p>Just have a api/v1/rest/ base path for modular well defined resources that can be used across your application, without breaking changes, or even shared to third parties.<p>Then have a api/v1/features for coupled endpoints that return non standard objects, and with a more flexible lifecycle.<p>Chances are you're better off having both instead of trying to cram all the use cases into one approach
The problem is not building a general purpose API, the problem is over thinking it. There’s a sweet spot where you build the API just slightly more flexible than your FE needs at the time, yet without wasting time on making it fit ‘all possible future use cases’.<p>Then you can later on whip up a mobile app if needed, let the clients use it, whatever. And evolve it accordingly.
This is how you lock yourself into a single front end design. And when you get ready for the next generation of your app or site, now you’re locked in and changing that front end design becomes exponentially harder.
The complaint about general-purpose APIs is valid. I've seen teammates, including senior ones, jump onto the bandwagon of some monstrous "data service" at work where the entire API to the frontend was an ORM. Absolute trainwreck.<p>This article advocates for another extreme that I've also seen at work. They invented some UI language in JSON and built some default JS components to render it. It works for very simple cases, but it's too rigid for anything slightly advanced, so the end result is some very clunky UIs and unhappy devs. You said your experience was bored frontend devs; that's usually a sign that their value is going to waste, and probably not because the backend devs can do their job better.<p>There's a good middle ground that's pretty common. You don't define the API to end all APIs, you don't pretend FE and BE are totally decoupled, you just have the frontend team ask for what they need and let the backend team serve it. Maybe you get an endpoint per page this way, but it's just sending back the data to populate the page rather than the actual layout. Maybe a few things are separate endpoints, but a reasonably low number.
I'd caveat that it can be a good idea to make it a general api if you're building a B2B app. These days, purchasing checklists often include "do you have a public api?" Saying no to that can be a sign of product immaturity that is worth trying to get ahead of, and having to maintain internal and external apis is a lot of overhead.<p>It also can be good as you scale to have an API interface you can have a services team learn how to work with to enable "special" flows for customers.
I don't know when we started splitting people into "frontend" and "backend" teams (FAANG influence?) and for what reasons, but 10 years ago we hired people with a general background, smart and curious enough to learn SQL, HTML/CSS/JS and whatever language you want to use on the server, able to build some end-to-end CRUD features on their own. And that's like what 99% of the companies need.<p>My point being: when you have the same person building the UI and the API, you avoid a lot of the problems described in this article.
It might be that for the author specific case (which we dont know in details) maybe this is a good approach.<p>In general I disagree with almost any idea that tries to fix some problems by adding coupling between components. I think the main thesis is where there is a false assumption:<p>> Your frontend can finally focus on presentation and UI. Your backend can finally focus on implementing exactly what’s needed.<p>If you make backend create one API call for each page, you will NOT get FE focusing on UI and backend on something else. You will get FE focusing on UI and BE focusing on UI and something else.<p>I do get the feeling of rebellion against common wisdom that is FE and BE as separate components.<p>When I was junior programmer (not suggesting here that author is junior, just talking about my experience) I often found myself rebelling against common programming wisdom.<p>Now, after more than a decade of seeing so many changes and request I think those old programmers that gave us that old wisdom about separating concerns and losse coupling are right.<p>I could boil down probably all old advice into the following 3 small pieces:<p>1. Write code. Not too much. Mostly simple, short and loosely coupled.
2. Go against common wisdom when you understand the tradeoffs. When not sure, pick the common wisdom.
3. You can maybe fix technical issues with more people, but can never fix organizational issues with code.
Based on my personal experience general purpose APIs lead to backends for frontends, which is a colossal footgun unless orchestrated by a mastermind. Even if you did have that kind of mastermind, if that person decides to leave you're left with a very expensive puzzle for everyone else to solve.<p>Here's my take: don't build general purpose APIs, build general purpose domain actions. A user making an account is a domain action. Sending a notification to the user is a domain action. Make doing each separately easy. Make doing both at the same time easy. Do this with all of your domain actions and now you have an easy way of building exactly the kind of endpoints all your front ends need.
As a user, this approach often leaves things in a difficult state. The front end works, but automating data access is a hard slog through inconsistent API that's not fully revealed. Reporting is dependent on what is planned for the front end, not what is needed by the user. Because the front and back are tightly coupled, everything is fragile unless it's baked in.<p>I think many business apps should focus on having an API be a first-class citizen, and there needs to be better standardization in how they're organized and used. GraphQL could be part of that solution. It's also nice when the API lets you do the things you can do from the front end as well as more data-oriented tasks. For example, in Zoho Books, reporting isn't automated by the API, you'd have to roll your own or script the UI. The API should cover both reading and writing data items like transactions and downloading a PDF or Excel report using the reporting interface.
My experience working on "medium sized" B2B apps in 10-20 people teams is that the cleanest way to design API-s is to have a regular REST API for the basic CRUD operations on the entities, and then have more specialized endpoints for specific pages, tables, dashboards etc. on top of that. Having specialized endpoints is kind of required, as the data often needs to be searchable, sortable, filterable and paginated, which would be pretty wasteful, or sometimes even impossible to do on the frontend. I find these kind of REST API-s pretty straight forward to design and implement for the most part, and as others pointed out, onboarding is extremely easy if the new developer on the team has worked in software dev at least for a year or two. This also makes it pretty easy and quick to transition to a fully public API if needed (although I have rarely seen this as a requirement).<p>Edit: fixed a typo.
I totally agree with the general idea, and this is generally how I build backends these days. If there are multiple clients, it's usually even ok for each to have a backend which talks to the "master" backend.<p>But I will never get on board with sending things like content or UI related stuff from the backend. I've seen too many times, engineers think "all our forms are the same, let's just have the backend send a list of input field names and types like 'address'". It's almost always a bad abstraction, causes pain on the frontend, and restricts the creativity of engineers and designers.
I read some of the HTMX essays [0] last week due to it being accepted into the GitHub accelerator program.<p>So, a fully RESTful API must output HTML. I'm not going to go into why but that's what Roy Fielding (the creator of REST), Martin Fowler and the HTMX guy(s) say.<p>The HTMX guy(s) also say that of course this fully RESTful API that outputs HTML is sometimes bad because you don't want to have to parse data out of HTML. So, the optimal setup is to have both a fully RESTful HTML API and the more common JSON API.<p>I also think that for the fully RESTful HTML API, it doesn't make sense for the outputted HTML to have any JS.<p>So, the question I'm pondering at the moment is, is a fully RESTful HTML API simply a website that doesn't use any JS? If so, then the optimal setup is to have an SSR website that doesn't use JS and a JSON API. Of course, under the hood, the website and the JSON API use the same lower level API (eg. SQL queries and back-end functions).<p>What's crazy for me personally is that this is exactly how I have set up Comment Castles. There's the no JS website [1] and the JSON API [2]. But I didn't build a no JS website because of REST, I just prefer websites that have no front-end JS.<p>[0] <a href="https://htmx.org/essays" rel="nofollow noreferrer">https://htmx.org/essays</a><p>[1] <a href="https://www.commentcastles.org" rel="nofollow noreferrer">https://www.commentcastles.org</a><p>[2] <a href="https://www.commentcastles.org/api" rel="nofollow noreferrer">https://www.commentcastles.org/api</a>
I have building most of my modern sites with NextJS and could not have been happier as it gives me the flexibility of directly quering DB, I dont have to worry about the general purpose API. But if I wanted to I can just easily build it too.
Don't think I could disagree any harder. Requirements change. Business needs change. You want your FE to be able to evolve independently without having to wait for the BE to implement the precise logic you need.
I see the point of the article, and even on a principled level I might agree with it (e.g., don't overly abstract). A few problems I see though:<p>1. If you make backend-only abstractions to keep your code even a little bit DRY, you'll have a duplication of code (both the abstraction and the BFF endpoint). I think it'd be better to go all in on the abstraction up-front.<p>2. This will impair the conceptual integrity of the system and arguably lead to development slowdowns in the long run. To quote Mythical Man Month: “I will contend that conceptual integrity is the most important consideration in system design. It is better to have a system omit certain anomalous features and improvements, but to reflect one set of design ideas, than to have one that contains many good but independent and uncoordinated ideas.”<p>3. Your ad-hoc logic will likely be duplicated anyways across pages.<p>4. A general purpose API makes security features like RBAC much simpler.<p>I think a general-purpose API is a well established abstraction you can rely on for pretty much any project.
This is good <i>general</i> advice. Sometimes you are building a general library or API, and sometimes there just happens to be a network partition between two components that make one module. My general rule of thumb is that it takes 3-5 times as long to build a library/generic API over regular code. It also requires a very different mindset.<p>Should you do that sometimes? Absolutely! In big companies you probably have entire <i>teams</i> doing this for API’s that are entirely internal. Just recognise that it is a <i>huge</i> cost and only do it when the benefits are likely to outweigh the costs.<p>That’s not to say that you should <i>never</i> think about generalisation when writing normal code, (one of my pet peeves is interfaces taking a single “something” when a collection could just as easily have been used), there are many ways code can evolve and some up-front thought can save a good deal of refactoring later. Just don’t write a generic library when domain specific code will do.
This pattern has a name Backend For Frontend (BFF)<p><a href="https://aws.amazon.com/blogs/mobile/backends-for-frontends-pattern/#:~:text=According%20to%20Sam%20Newman%2C%20the,one%20general%2Dpurpose%20API%20backend" rel="nofollow noreferrer">https://aws.amazon.com/blogs/mobile/backends-for-frontends-p...</a>.
This is BFF pattern described many years ago. Here's the standard way I build this kind of thing: Develop your APIs per functional or really per system. One for content, one for identity, one for ads or whatever. Then you build an orchestration tier that does pretty much what OP says. It stitches the various services together and returns a page model. The ideal is to reduce round-trips and cognitive load on FE dev. If you need the top 3 pieces of relevant content, plus an ad plus the user's first name, return all of that and nothing else. The last piece is just SSR. Use next or nuxt or whatever and you can output HTML on the server or stich it on the client with one codebase seamlessly.<p><a href="https://samnewman.io/patterns/architectural/bff/" rel="nofollow noreferrer">https://samnewman.io/patterns/architectural/bff/</a>
The way HN is build is the best way to build web applications.<p>There is a concept of a "page". A page is loaded as an html page. This thread for example is a page.<p>And then there is JavaScript which does all kinds of dynamic stuff on a page. Like when you update this commment or when you collapse/expand comments.
Counterpoint: I did this and it worked out great. We ended up wanting to support direct API access from our customers and we were already in a good place to do so.<p>YMMV. An observation I have is that really flexible APIs make it easy for the frontend to make small changes, instead of needing to coordinate with backend changes. On the other hand this can lead to maintenance problems down the road as it’s hard to control exactly what data/state your system can transition to.<p>I view this as one of the best pieces of tech debt to take on in an early-stage startup, basically keeping your options open and minimizing short-term friction, at the expense of taking on a bit more cleanup after you find PMF and start to make your backend more robust for the usecase you are scaling.
this is fine but makes the backend extremely slow and hard to maintain. it's effectively just glorified RPC<p>- restful api low logic on backend and lots of logic on front-end<p>- grpc style as the author suggests, more logic on backend no logic on front-end<p>- keep api restful on backend, add backend for front-end(graphql/rpc), front-end remains simple, most logic is in the middle. this also allows you to isolate presentation spaghetti code in one place, keeps your backend api clean for use for other clients<p>worked in all 3 probably having a custom presentation layer works best but require more setup upfront. another advantage of having a restful api and have the front-end do more work is being able to incrementally load data into the UI therefore reducing TTI/TTFB
This is entirely backwards.<p>Don't build a general purpose API so your front end can have half the the logic outside.<p>Just build it the way you would as if it were local, and then hook it up to a back end with a git-like synchronization mechanism. You know, the same way you do all your own development.<p>If you don't know how to do that, maybe you could learn that instead of arguing over REST vs GraphQL, or whether your line format should care what boxes are on the page.<p>All I know is, it's fantastic to be able to add features to a front end, persisted in a back end, without having to write code on both sides.<p>"What about validation??"<p>Guess what, if users each have their own workspace, isolated and data driven, you don't need to worry about one bad request ruining your whole service.
General purpose API helped us when we had several features to implement in a row on a tight schedule: when I was busy implementing feature N+1, our frontend dev was still polishing feature N (with changing UI/UX requirements), and she didn't need me (the backender) because the backend just exposed the model as is without knowing what the frontend looked like. She could make lots of changes to the UI without needing any changes to the backend. Yeah it translated to more API calls but it allowed us to decouple our work completely and deliver more features in parallel.
It sounds almost like the author is advocating for a really dumbed down BFF layer (backend for frontend) but what they are missing is behind the bff layer you would have general purpose apis. And if I interpret the article to the extreme what is the difference between this pattern and how html is currently served. Salesforce works sort of similar to what is described and it’s a nightmare, these restrictive ideals in my experience just aren’t good in practice because they tend to slow down development.
And the htmx-ification trend continues. I guess this is sort of the counter movement now to all the API-First/Data-First/SPA-First evangelism of the last few decades.<p>I don't quite understand why though. Or rather, why those posts always seem to have an intense emotional dislike to anything data-driven.<p>What exactly is wrong with just using React? Or, heaven forbid, plain Javascript, which browsers have spent the last decades optimizing it make working with REST APIs and JSON as easy as possible.
The `Accept` HTTP header is there to prove your frontend is using "dumb" data. <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept" rel="nofollow noreferrer">https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Ac...</a><p>I think the author is generally correct that all data should be provided in a single request. And to take it a step further, you should be able to change your accept header to JSON to serve an API. API/dumb-frontend aren't mutually exclusive.<p>In fact, this is what both GitLab and GitHub do. Try it out!<p>`curl -L <a href="https://github.com/simonw/shot-scraper">https://github.com/simonw/shot-scraper</a>` (defaults to text/html)<p>`curl --header "Accept: application/json" -L <a href="https://github.com/simonw/shot-scraper">https://github.com/simonw/shot-scraper</a>`
Nice article<p>This is one thing I’m loving about Remix. It’s how the framework works, so there’s no need to enforce this pattern or educate folks about it.<p>AND Remix’s nested routing still has you break down the data loading into a couple different parts (1 per route segment).<p>So it feels like you’re not loading everything in one place, and may be less likely to make people feel like they’re doing something “different” or “wrong”. It’s
I am not a big fan of building extremely fine grained general purpose APIs for frontends. A lot of the burden of juggling with data and presenting it is shifted to the UI layer. I am also not a big fan of building a composite API for "pages". Now you have a tightly coupled frontend/backend communication. What happens when we split the page or have to change the format of the data? Also the response of such an API can be quite big and nested. Ends up being a dump of data with poor documentation.
I would try to find a middle path. Building composite APIs which have a concise purpose for the frontend but are modular enough to be reused across different areas of the application.
Also, I feel that most of the problems discussed in the post are amplified when we have different groups working on the frontend and backend. If a single team is responsible for both the backend and frontend, API decisions are localized and can be changed as the development progresses.
The past 2 years have seen some advancements in full-stack frameworks with streaming components. Such as NextJS with React Server Components or .NET Blazor.<p>Those would be my preference for an app that doesn't need a public API. If each partial layout and page component does it's own data loading server side, you can skip GraphQL or making a Full Page API and partial update APIs.<p>Part of the problem with this is organizational though. For the past decade teams have largely been split between frontend/backend who typically work in 2 completely different languages/frameworks. The steaming components approach is a switch back to full stack and a single language/framework. Also every language doesn't have one of these streaming component frameworks, so it's not really possible to do an app completely in Go for example.
> This is similar but not quite the same as Server Driven UI1. Perhaps we could call it Server Informed UI.<p>I think we should just move back to server side rendering, JSP and even ASP were great, plain HTML, some JavaScript where desired since we can't seem to get away from JS.
I read this and got to the end, and laughed because that's what we're working on (more a composition tool from different data sources using a headless CMS and a Knowledge Graph) - so in the end we do need a general purpose API since that's part of the USP.
So basically an old style MVC framework style app like RoR, CodeIgniter etc but made with a JSON response the describes the page rather like Shopify's Store Theme 2.0?<p>Sounds great. Now since you have access to the server code (unlike Shopify's system described above) just return HTML and use your JS flavour of choice in the places where you need heavy JS ... like we used to make web apps.<p>The happiest web devs I speak to are those working in the older MVC style, mainly RoR people. While everyone in AWS/Serverless/JS land is burning out and miserable with the house of cards stack we are balancing React on top of.
I've built both models (and more too) over decades.<p>There are lots of questions one might ask before deciding between these two (or other) approaches:<p>* Where does this team want the boundary between client and server in terms of user experience, server load and substantial UX interaction latency?<p>* Can this frontend team independently plumb a changes all the way through the database?<p>* Are backend teams always available for (or interested in) every minor update?<p>* Are both halves of the application deployed on the same schedule?<p>These are a handful of the first questions I'd ask before trying to push either solution at this point in time, the answers would likely lead to more questions.
Have to disagree with this. API is not always for FE. It can be consumed by other service, or a script. Making generic API helps reuse of common API across web pages. For example notification, user profile.
What’s missing from this article is a discussion about 1) team composition and software development lifecycle, and 2) which libraries are available to help easily provide and consume the obvious RESTful operations.<p>1. Team composition<p>If you have a separate backend developer from front-end developer (or worse, on a completely separate dev team), then making a separate endpoint for each page means you have to manage the feature dependency. As in, you need to make a ticket for the backend work first and the front end work can only start once the backend work is finished. And you need to do this for every single new page you make. On the other hand, if the backend team in advance just makes a generic rest API that provides all access to all of the obvious resources, it gives the front-end team the freedom to develop on their own timeline.<p>If all your teams devs are full-stack, this is simplified a bit but still you have the problem of deciding to intelligently architect your data access layer to not have massive amounts of duplicated code.<p>2. Supporting libraries<p>Often it’s possible on the backend to just easily make restful crud for every single resource that makes sense. A single backend dev can do this in one go without much conversation besides the initial one about access policies. Similarly, the are often front-end libraries that simplify not only writing getters for these endpoints but also for things like handling local caching, business object creation from JSON, and refetch logic.<p>Obviously the libraries that are available and how well they integrate with your workflow will depend on your front-end framework. React, for example, has libraries that directly connect your rest access into specific components.<p>—<p>A caveat: obviously the pro-con landscape changes if you have serverside operations that either:<p>A) feature some interaction that is sensitive to race conditions, B) requires a guarantee that one data type not get written unless the a previous write succeeded, or C) would require special queries for performance reasons<p>In these cases, I’d say make a custom endpoint to encapsulate the correct/safe behavior. But these one-offs can be created only when they are needed. No premature optimization/complexity is required.
Better, just don’t write an HTTP API for your front end. Use a server side framework. Done.<p>It’s a pain coming into a project that was built the way the article recommends. Endpoints become RPC calls instead of resources serving entities. The hodgepodge of “API” calls becomes difficult to scale horizontally due to implied (and never documented) data dependencies. So you miss out on transport layer caching, entity caching, and a host of other goodies.<p>All because your front end “framework” wants to live in a separate codebase from the server.
Great article.<p>We used to call this common sense. It's insane we drifted so far from being sensible.<p>I genuinely think 90% of frontend developers should not exist: the web would be better and companies would have better products.<p>I include myself in the frontenders, I do terrible apps which should just be simple static pages with a sprinkle of js - in my defense, I need the money and nobody listens to me, they say this is modern frontend development.<p>For my tech not-savy clients I can deliver awesome and simple solutions without using the dreaded R framework.
I'm finishing a project now, using exactly this design pattern. Sort of backed into it, motivated pretty much by the issues outlined. In addition, I wanted something that is clear and sustainable far into the future. The simplicity of this approach supports that. Quite liberating.<p>Complexity is the enemy.<p>True, one might reasonably propose a number of what-if objections. But for many (most?) projects), imo this is a good approach.
An alternative to what's suggested in this post, how about going API first or even API only? Don't build a frontend at all, just build an API. E.g. you can deploy things on fly.io just by using their GraphQL and REST APIs. The advantage of focussing on the apis is that other developers can much easier integrate with your service and embed it into their own applications.
I’m going to get zapped once again, but if you’re building complex applications, custom read models automatically updated based on events from operational writes is the optimal way to connect a front-end to APIs.<p>Each read model should have a distinct business purpose.<p>Generic models will only confuse maintainers and they’re very likely going to see such code as brittle and tech debt.
If you do proper hexagonal architecture it wouldn't actually matter and you can replace REST with graphql or feature-based endpoints. Before you rip that out, start with that. (YMMV and don't apply every piece of advice to every problem, that's the biggest problem)
I write all my api code using a business logic “service” layer and a data ops “repository” layer.<p>The endpoints are by feature not entity, although most of the time they overlap.<p>This lets me move fast while keeping it simple to build the UI whether it’s mobile or web.
I've done this, and agree.<p>But it was a good exercise for me, and I ended up using the general-purpose backend for a specific frontend.<p>It's just that it's way overkill. Much more complex than it needs to be.<p>But it works really, really well, and is secure as hell.
Very similar sentiment to this article <a href="https://bower.sh/dogma-of-restful-api" rel="nofollow noreferrer">https://bower.sh/dogma-of-restful-api</a>
It's also an ideal vector for scraping your site-specific data if it's an XHR request, typically an enumerating id or something a sitemap will spell out for more sparse IDs.
doesn't this require you to nail down design requirements?<p>If the designer gives a few different comps to try out, or wants to A/B test something, they'd have to align those changes with both backend AND frontend people to make sure they both know what the changes are.<p>If the data dictates exactly what the frontend should look like / placement of content, shouldn't the backend just send styling / html / app code directly, and just skip frontend completely?
Think this is describing other frameworks that do this. Isn't this how ELM works? Or ELM architecture in general?<p>This is kind of how some 'functional' web api's work.
When are we going to get away from all the YAGNI engineering that has sold short the promise of the Web for more rented silos, and get to something more like HATEOAS?
This only works for small projects.
Data-heavy frontend usually sends multiple requests to allow async rendering of different parts of a page with different loading times.<p>This also doesn't work if your design changes a lot. AKA a design change will now mean a backend re-design too.