Hacker News new | past | comments | ask | show | jobs | submit login

Whether it was the intention or not, I find GraphQL solved a fascinating problem: it let front end developers move faster by greatly decoupling their data needs from the backend developers.

Backend developers describe the data model, expose it via graphql. Front end developers, often ones who never met those backend developers, can see the data model and just use it. They can change what they're querying on the fly, get more or less as they see fit.

It lets everyone move faster.

But as a backend developer, I actually fucking hate it, myself.




I get specialization, but are there any other good reasons to divide product teams between frontend and backend? I guess it also helps establish patterns and contracts, but I think those are only helpful above a critical mass that I haven’t reached in my career yet.


It depends on the kind of application and scale. Consider a large and complex application like Discord or Figma. Past a certain point, it's hard for anyone to know how every single detail works.

You should probably be comfortable enough to work with both ends of the spectrum, but specialization allows you to do a much deeper dive into complex subjects.

A backend engineer probably has a much deeper understanding of every little nuance of their prefered database. A great backend engineer can make sure that you're getting near-optimal performance from every important query.

A frontend engineer probably knows about various UX techniques along with how to avoid unecessary reflows and repaints. A great frontend engineer can implement a UI toolkit as well as advanced techniques such as windowing.


Right, that’s specialization. IMO those people still belong on the same feature implementation team for most organizations out there.


The reason is to scale teams. It’s not the only way to do it—you can also have vertical teams—but it’s a common one because frontend and backend have different technical considerations. The downside is the product can lose cohesion as developers get tunnel vision. Of course all big teams suffer from a version of that problem depending how the lines are drawn.


In a small organization there isn't generally any reason to divide the teams between front and back end. As you've alluded - once you have many clients you'll want to separate responsibilities in order to increase velocity.


Frontend teams are often feature partitioned at least in larger orgs. There will need to be some level of feature level backend knowledge to be had somewhere, but backend problems are often feature agnostic. Many companies conflate backend with platform, which have subtle differences, but end up working with similar results. Specialized backend teams work to develop a really good "platform" feature while frontend teams focus on developing customer/product oriented features.


This is something I’ve wondered as well. Coming from the military and occasionally working with spec-ops, I would say having a few “full stack” teams would be the way to go. I am just a lowly dev though, so what do I know?

The separation of front/backend has always been mildly entertaining to me and I’ve worked on both teams. Btw, if you ever want to cause a political mess, just submit a PR to add a new API endpoint to the backend team that “doesn’t have the time” to work on it. Woah boy, they will get mighty pissed. As a backend engineer these days, it would be a blessing to get free work from another team… I don’t know why they were so pissed that one time.


Well, if you are truly wondering, I think I can give you some intuition about "why they were so pissed". Obviously, I don't know what were the facts of the situation, and if they really should've been pissed, but I can explain the typical mindset.

The main idea is that writing some code to achieve any particular effect in the system is typically easy. But writing code, that is efficient and maintainable isn't easy. So, there's a team X, which has people working on some specific system. They own the code. To them, their work isn't quite about "implementing requested features". It is about inventing proper abstractions that both reflect the logic of the requested feature and reasonably anticipate the logic of any future feature requests. They want to avoid having 2 implementations of the same thing, they want every piece of code to be idiomatic to their system, etc. And they are right thinking like that, BTW. Every new developer they get is treated with some suspicion at first, and when he learns the idioms of the system he becomes a honored member of the team X. If he fails to learn them, he gets fired or passed to another team, where he may turn out a better fit.

So, for the members of team X, they are professionals, who know how to work on the product and on the system X. Members of other back-end teams are probably not, even if they are good devs otherwise. Some frontend dev — doubly so. Some junior frontend dev coming from military or helpdesk or whatever — triply so.

So, you may think that you are a great and charitable developer, who just implemented a Feature. But to them, you are a lowly ape who made a wobbly hut out of some sticks and leaves that is going to fall down now any moment, and it's going to fall down on THEIR heads (and you will be long gone).

Worse than that, they understand, that other non-engineers (like their manager) also are prone to mistaking a wobbly hut for a Feature. And you basically humiliated them in front of these people by "solving" their problems (while in fact you created more problems). So it gets political here. In fact, because of that, even if the above is not a fair description of your work, they kind want it to be fair, they want you to fuck up, because it at least makes it easier to explain why your help wasn't a real help.

And, in all fairness, it is kinda unlikely that a guy who is new to a codebase didn't fuck up in any way, even ever so slightly. Especially if that's a kind of guy who doesn't understand why dedicated back-end and front-end teams exist.


> BTW. Every new developer they get is treated with some suspicion at first, and when he learns the idioms of the system he becomes a honored member of the team X. If he fails to learn them, he gets fired or passed to another team, where he may turn out a better fit.

Oooh, that's an interesting observation. This was so long ago, before I really knew about this attitude. Since then, I've been on these teams and despise that attitude. I didn't even know that attitude existed back then, so this is indeed a possibility.

> And, in all fairness, it is kinda unlikely that a guy who is new to a codebase didn't fuck up in any way, even ever so slightly. Especially if that's a kind of guy who doesn't understand why dedicated back-end and front-end teams exist.

Hah, they couldn't find any fault with the code, the unit tests were even better quality than their own. I also submitted several other PRs fixing bugs that I discovered while writing unit tests. Their reason for not merging the code, after reviewing it, was that the implementation "didn't seem scalable" despite including performance tests showing that it was both faster and used less resources than some of the more popular API endpoints.

When I joined, they kept having GC problems and I pointed out that they were using the Desktop GC method instead of the Server mode GC (this was C# 3.x?) and they didn't even know that that was a thing. They didn't like how some frontend engineer seemed to know more about C# than them.... I imagine that it was a combination of a lot of things, me knowing more about their language than them and not being on their team, plus submitting PRs "showing them up."

This was my first time working at a company with more than 10 devs, so I was used to just getting shit done and not worrying about politics. These days, I know better.


They were likely pissed because they were afraid it would make them look bad to management - "How come no one on the backend team could find time to build this, but one front-end guy managed to despite his regular workload?"

It's an easy conclusion to get to, whether justified or not.

No one likes being made to look incompetent, regardless of whether they actually are.

I have the impression you didn't ask for permission before you did it - the dynamic is wildly different if you start things off by asking if they'd be okay with you taking some time to build it, then involve them in your process as much or as little as they want.

If that's what you actually did, then my analysis is way off.


I think you are saying why not combine specialists on one team vs the “everyone is fullstack+devops” amateur hour dystopia that is becoming all too common?


Back in the day we call this role Webmaster. Being able to manage your server, write your code and design the website was what a true developer tried to achieve.

It is strange to see developers preferring to stay in their isolated environments and not wanting to touch the entire stack.


It's not strange at all - it takes months of work to get productive with insert whatever tech stack here even when it's within your experience domain. Problem domains are really separate. Toolchains and languages are different. It's already hard to find people competent on one stack/field - hoping to find a team of competent "full-stack", in the broadest sense of the word, is probably prohibitively expensive.


This actually made sense back in the day. Now there's significantly more complexity for each part of the stack, tooling, distributed design patterns for scaling, etc. We don't really have "websites" any more, for example. We have apps that run in the browser.


> the “everyone is fullstack+devops” amateur hour dystopia that is becoming all too common?

What a weird thing to say. That was the original state. At some point people started splitting things up because they felt that would be better (or they just weren’t capable of grasping more than one thing?), but I’m extremely sceptical of all this specialization.


I think we’re all amateurs at some part of the stack. I am not the CircleCI dude in my current gig, some other competent engineer is, but I’ve been the Jenkins dude in the past because I cared about it the most.


You can have N frontends for one backend. If you need a new iOS app you will probably hire a team of iOS developers, not have all of your product teams learn Swift.

If your API looks like this...

  /ios-app/v1/landing-page
  /android-app/v1/landing-page
  /android-app/v2/landing-page
  /windows-mobile/v1/landing-page (legacy)
  /web/v5/...
where each platform has its own subtly different UI structure, the ability for frontend teams to get basically an arbitrary JSON structure of their choosing starts looking worth the extra work on the backend.

You might not encounter this problem at any point that's fine - there are other ways to avoid it, like having a cross-platform codebase. I have "hand-rolled" similar solutions to the GraphQL field selection before, and I would use the GraphQL protocol if I were to do it again today.


It could be the contrived example, but REST URIs are supposed to represent resources, not UI pages or elements. When the endpoints start to become coupled to the UI the backend can get messy, as you described, very quickly.


> good reasons to divide product teams between frontend and backend?

People specialize in different things. A great React developer may not be a great Java developer, and vice-versa


An intermediate Java and React developer is more than the sum of the parts. Especially when considering a whole team.

You may need one or two really great React and/or Java developers.


From a management perspective, the fiction of the full stack developer that is equally skilled at everything is the easiest. You stick with that until you complicate your architecture (wisely or not) to the point where having specialists outweighs having to manage multiples queues of work and dependencies.


Worse approach imo.

Nowadays a full stack dev is an intermediate Fe dev, with junior backend skills. He will make your backend un-maintainable. Get a proper master on a proper contract rate to design your architecture.


To me it's a weird way to go about this decoupling. Another way is you can just keep your own view-model client side and abstract the backend data with that.

FFBs and GraphQL is a way to tightly couple to a backend system and then have that backend system loosely coupled.

I guess its all 6 of one, half-dozen of the other, but I usually prefer to just handle things client side. You can maybe get less data transfer optimization but that's down the road from the fast development stage, anyway.


I thought it was supposed to do this, but then discovered that it has no way to express joins.

Has this been addressed? I don't see how you can decouple the back-end data from front-end queries without that.


You can do something like this. This query can be created and run on the client:

``` const SAMPLE_JOIN_QUERY = gql` query ($main_data_id: String!) { mainData( main_data_id: $main_data_id) { id main_data_field_1 main_data_field_2 main_data_field_3 related_data{ related_data_field_1 related_data_field_2 related_data_field_3 } } } `; ```


https://news.ycombinator.com/formatdoc may interest you

    const SAMPLE_JOIN_QUERY = gql`
    query ($main_data_id: String!) {
      mainData( main_data_id: $main_data_id) { 
        id main_data_field_1 main_data_field_2 main_data_field_3 
        related_data {
          related_data_field_1 related_data_field_2 related_data_field_3
        }
      } 
    }`;


Thanks!


in other words, it's up to the folks writing the resolvers to manifest and implement that join as a nested field.


Which means a lot of the time they end up just caching as hard as they can and hoping that's good enough.

(which is often, honestly, an entirely rational decision in terms of prioritising limited resources, but still makes me sad)


Dataloader does this IIRC


Right, but on the backend someone had to think ahead of time that somebody would want to JOIN between those two types, and remember to put the field in place, and implement the JOIN.


Curious as to why you hate it specifically. Because what you could be doing is exposing every table / field automatically based on permissions (which you could set up a system where you don't even have to be involved).


because either the boilerplate is massive or the libraries do so much for you that you have to specialize in understanding the libraries magic - front-end plus back-end code for graphql is almost always more than a traditional REST api and I mean a lot more code, not just a bit more, so more code is strongly correlated with more problems. The exception is when you use heavy libraries that have magical APIs. Then you end up with teams who understand the API and have no idea how graphql actually works, which is probably an even worse problem.


What tooling are you using that requires a massive amount of extra code? You need to define the schema and write resolvers, but that's sorta similar to what you might do in REST on the backend.

On the frontend, you have a choice to use some of the heavier libraries that support all of the features (like subscriptions) - but otherwise, you can just POST a gql query to the server and it will return a blob of json, which really isn't so much more than REST.


Why use graphql at all if you are going to use it just like a traditional REST api? You don't get much of a benefit from the client selecting which fields it wants, the backend probably fetches the entire DB row anyway so why not just send the whole thing over?

The limitations of the query language make code size explode the moment you step outside simple toy examples. It doesn't have any concept of a JOIN, or of the actual relationships between your types (graphql has no concept that me == me.parent.child). You end up writing data loaders for every type so that loops in your schema can be resolved efficiently.

Managing permissions is so much more of a pain compared to REST because exactly what data is returned is so much more dynamic. If you have some confidential data nested 10 layers deep in the query, you get two choices. Either fail the entire query with a NotAllowed based on one deeply nested field that the client maybe does not even care about, or you have to make your schema super loose and make every single field that's subject to permission management nullable. So much easier on a REST endpoint because the response is more constrained.


You use graphql when you have many consumers of your data, whether other teams at your company or external data partners (which is how my team uses it). What it does is make it so that you don't have to provide a bunch of custom endpoints for these users, they can get exactly what they need without your help. You're also able to get performance gains dependent on the implementation.

Our code size for our graphql endpoint has remained totally unchanged for the past couple of years. It took only a few files (of admittedly complex code) to automatically set it up so that it would automatically provide all models via the graphql schema (and a separate permissions implementation restricts access at each level of the schema). It updates automatically whenever we add new models or permissions. This is built on top of Rails and the graphql gem.


Honestly it's mostly just lack of familiarity, which is getting better every day.


e.g. postgraphile


It sounds like it is promoting a siloed cogs in the machine type of work ethic. Where you are either front end or back end and no one is thinking end-to-end about the system.


I think the causality runs the other way. Once the frontend had gotten so complex that it required a specialized team, solutions arose to reduce the back and forth necessary between frontend and backend teams.


Sr enough developers who's role expands beyond a single team, architects, product managers, product owners, the list goes on for the roles of people who are often task of thinking big picture about the health and "end-to-end" picture of any given software project. Your narrow synicism makes me assume you don't work in a company that has a large dev org. People specialize and if you want to be the learn and do everything person, you'll find that you're doing less and learning more which isn't a good fit for most orgs.


You are right I have worked in relatively small companies (and "bigger small" companies that were not doing web).

My concern is not specialization which I think is necessary for a larger company. It is more the technical solution of "here is GraphQL now your teams don't need to talk and you don't need anyone thinking end to end". I can't believe that is helpful.

I may have created a strawman though?


That's generally true for sizable companies. Small companies can and do use full stack devs.

Segmentation makes some sense but the industry is lacking end to end thinking as you point out.


Why do you hate it? What tooling are you using? I found it fairly painless in Python - Graphene/Flask.


If all you do is expose simple models, it's fine. But then not much different than an auto-generated REST-api. But if you want to query deep, list of childrens etc you quickly get into queries that are very hard to write on the backend (n+1 issues quickly pop up etc). To solve those you need to write complicated loaders, which all should be very general in nature and thus you can't rely on two fields backed by the same data sharing a query without doing something special. Which is much more hassle than just writing whatever join you want for a tailored endpoint.


The N query is the general case which devolves to the scaler query with a list of ids with only one id...


I joke mostly. Coming from a REST based background it was really foreign and convoluted to me.

Until I understood the point, the organizational decoupling. Then it clicked why it's great.




Applications are open for YC Winter 2023

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: