[HN Gopher] Migrating Netflix to GraphQL safely
       ___________________________________________________________________
        
       Migrating Netflix to GraphQL safely
        
       Author : theptip
       Score  : 146 points
       Date   : 2023-06-18 16:33 UTC (6 hours ago)
        
 (HTM) web link (netflixtechblog.com)
 (TXT) w3m dump (netflixtechblog.com)
        
       | nf17 wrote:
       | Is JS/Express/Apollo still the goto graphQL server implementation
       | or C#(HotChocolate), Java, go etc are widely used too? On the
       | client side(for mobile), AFAIK iOS(Swift) and Android(Kotlin)
       | does not support GraphQL natively? are there 3rd party libraries
       | that can be used?
       | 
       | Edit: Added Apollo
        
         | asabla wrote:
         | We've been using Hotchocolate for over a year now I n a
         | project. And the experience has mostly been pretty good.
         | 
         | And pair this with their Blazor client called StrawberryShake.
         | And your production levels are pretty nuts.
         | 
         | So to answer your question, yes people do use other
         | alternatives
        
         | gavinray wrote:
         | The "go-to" GraphQL server implementation varies based on
         | language.
         | 
         | Here are the popular ones to my knowledge:
         | 
         | - Node.js: GraphQL Yoga + Fastify, Apollo Server
         | 
         | - Java/Kotlin: Netflix DGS (built on top of Spring Boot)
         | 
         | - Scala: Caliban, Sangria
         | 
         | - Python: Strawberry, Graphene Django
         | 
         | - C#: HotChocolate                 > "On the client side(for
         | mobile), AFAIK iOS(Swift) and Android(Kotlin) does not support
         | GraphQL natively?"
         | 
         | GraphQL queries are just HTTP POST queries with a JSON body.
         | They're supported everywhere.
         | 
         | If you want specialized tooling for them, Kotlin and Swift both
         | have great strongly-typed GraphQL libraries.
         | 
         | Apollo publishes libraries for both:
         | 
         | - https://www.apollographql.com/docs/kotlin/
         | 
         | - https://www.apollographql.com/docs/ios/
        
           | a_wild_dandan wrote:
           | It appears that fastify can't keep their website up.
        
         | Justsignedup wrote:
         | I've been using json-api with graphiti in rails. And I gotta
         | say the massive gain from it is that it's all rest and a
         | trivial client impl from scratch if necessary.
         | 
         | Couldn't recommend it more.
         | 
         | Have to say. Most json-api impls suck, so graphiti has been a
         | game changer for me.
         | 
         | N+1 are a problem buuuut it forces you into good model designs
         | and good tools like graphiti and the latest rails show you the
         | cause of the n+1s so it's not so bad to debug.
        
       | latchkey wrote:
       | I wonder how many hidden n+1 problems there are. Reading the blog
       | post, it looks like they mostly only tested existing pathways as
       | part of the migration. Who knows what random requests could do.
        
         | rand_r wrote:
         | Yes, this is the biggest problem with GraphQL that I haven't
         | addressed anywhere.
         | 
         | The architectural beauty of GraphQL is that you can write
         | isolated, functional nodes that only have to know about their
         | object type. For example, the User node only has to know how to
         | get the user's last_login, active status, and return a
         | reference to another node type like a profile Image.
         | 
         | Inside the User node, you are free to write code (e.g. Java or
         | Python) that can compute which Image node is the right one to
         | return. i.e. you can write:                 class UserNode:
         | def get_user_profile_image() -> ImageNode:               return
         | some_arbitrary_function()
         | 
         | There is no way I've seen to square this kind of arbitrary node
         | computation with the desire to write an optimized SQL query
         | that selects all needed information in one big-ass statement.
        
           | valenterry wrote:
           | The exact same problem exists in an typical REST api as well.
           | In both cases you have to add a specialized endpoint to
           | retrieve multiple results.
        
           | striking wrote:
           | You could use https://github.com/join-monster/join-monster,
           | but setting that aside it's usually enough to use Dataloaders
           | that resolve based on some source ID, with some server-local
           | caching on top if latency becomes an issue.
        
         | gavinray wrote:
         | This is Netflix, not some amateur-hour implementation copied
         | from a blogpost.
         | 
         | The de-facto GraphQL Java library comes with dataloaders built-
         | in anyways:
         | 
         | https://www.graphql-java.com/documentation/batching/
        
           | voz_ wrote:
           | While Netflix has a good reputation, we should not give
           | blanket benefit of the doubt, especially since the parent
           | comment was a rather interesting and inquisitive one.
        
         | 727374 wrote:
         | Dataloader (https://github.com/graphql/dataloader) eliminates
         | many n+1 issues. Basically, entity requests are queued up
         | during evaluation of the query and then you can batch them up
         | for fulfillment. It's a great addition to other asynchronous
         | contexts as well.
         | 
         | WRT random requests, there are libraries for query cost
         | estimation you can use as a gate.
        
       | gumballindie wrote:
       | Curious how they handle GQL injections. Most devs using graphql
       | have no clue what they are as the majority just cargo cults new
       | frameworks to keep themselves busy.
        
         | valenterry wrote:
         | What are GQL injections? You mean something like SQL injections
         | that come through the graphql API?
        
       | saurik wrote:
       | Why? What problem did this solve for them? I use Netflix _a lot_
       | , and I use it on AppleTV where I get automatic updates to the
       | device and the app... the app has never changed except to get
       | slower over the years (and I mean a _lot_ slower). There is
       | absolutely no new functionality they have ever deployed... isn 't
       | the app "done"? Is there some serious scaling issue on their
       | backend that is causing the perceived frontend slowness that this
       | will fix? Is this going to massively decrease the costs of the
       | backend? Or is it just that the engineers are all bored and can't
       | accept the idea that the product is either 1) done or 2) needs a
       | new direction (instead of some new tech)?
        
         | thephyber wrote:
         | > isn't the app "done"?
         | 
         | Netflix is an ecosystem, not just the frontend app for Apple
         | TV. Netflix is pretty close to a vertical monopoly for some of
         | its content. Fund-raising, planning, development, post-
         | production, translations/dubbing, preparation for distribution,
         | and distribution. Your idea of viewing a video content on the
         | app is only the last 20%.
         | 
         | Also worth reminding people that the AppleTV app is not the
         | only app Netflix supports for viewing. There have been
         | dozens/hundreds of different apps and most are still actively
         | supported.
         | 
         | Also, they are a company, so they are always looking to be able
         | to optimize and cut costs.
         | 
         | It's worth staying curious and asking why before assuming you
         | know more than the engineers who have to work "behind the
         | curtain".
        
         | mkwarman wrote:
         | I have definitely noticed and been frustrated by what you're
         | calling out here. There always has to be something to work on,
         | even if that thing might invalidate a significant amount of
         | previous effort or cause regression. As a developer myself, I
         | guess it is good for me, because it means job security. And
         | maybe that's why there's always something to be added or
         | changed or re-created on the products I've helped develop - to
         | ensure all the individual contributors have something to keep
         | them busy. But it definitely is frustrating that it seems like
         | an app being called "done" is extremely rare nowadays. Though I
         | suppose developers didn't really have the choice to continue
         | development indefinitely back before the internet allowed
         | "miscellaneous bug fixes and feature updates" patches to be
         | pushed weekly.
         | 
         | Edit: I just noticed who I was replying to. Thanks for your
         | work on Cydia and in the iOS jailbraking scene at large. I have
         | lots of fond memories jailbraking and installing all kinds of
         | weird tweaks on my iPhone 4 back in the day.
        
         | Dudester230602 wrote:
         | It is surely solving a promotion problem and a bonus-getting
         | problem for someone in their hierarchy. Plus it is making the
         | world a better place through constructing elegant hierarchies
         | for maximum code reuse and extensibility and through minimal
         | message-oriented transport layers.
        
       | revskill wrote:
       | How to avoid N+1 query ? You don't join SQL.
        
         | lolive wrote:
         | I am not sure I understand that n+1 select issue with graphQL.
         | 
         | On my project, we generate SPARQL queries [to simplify, it is
         | not so different from a GraphQL query] and we send it to a SQL
         | translator that then sends that SQL to a Spark cluster. It is
         | reasonably efficient, and extremely flexible.
         | 
         | Of course, this is a single database use case, but I don't see
         | any n+1 select involved here. And I do not understand how
         | single database graphQL servers cannot work exactly the same.
        
         | x86x87 wrote:
         | brave to assume they are avoiding this problem :/
        
       | toomim wrote:
       | Falcor was cool. I'm sad seeing it go away.
        
         | jFriedensreich wrote:
         | I would not say it is more going away now than in the last 2
         | years of not getting upstream support from netflix. If anything
         | this step at least makes clear this is a dead end at netflix
         | and we can think about how to go forward with what is/was great
         | about falcor!
        
       | itake wrote:
       | I don't see the value ins Graphql. Most apis rarely change and
       | the complexity of supporting queries is not worth the time saved.
       | 
       | Graphql was a cool experiment, but I'm sticking with
       | rest/protobufs
        
         | rand_r wrote:
         | The original motivation was to reduce the number of network
         | requests made on cellular network-connected mobile devices,
         | both to save on power consumption and reduce latency for the
         | user. It off-loads a lot of complexity and computation from the
         | client to the server, and make sense if want to create as good
         | a mobile experience as you can.
         | 
         | In terms of code architecture, it drastically simplifies
         | frontend code, and overall reduces backend code and
         | boilerplate. It's extremely elegant and nice to use over
         | creating custom endpoints for every use-case, but the N+1 SQL
         | query problem is a giant thorn.
        
           | andrewingram wrote:
           | Kinda, by all accounts the original motivation was to solve
           | the proliferation of endpoints. Everyone was already writing
           | per-screen endpoints to solve the network requests problem
           | (which, contrary to what many believe, wasn't magically solve
           | by http2), but they were doing it in a way which played out
           | in several ways:
           | 
           | 1. Having to make a new endpoint every time your frontend
           | changes
           | 
           | 2. Not making a new endpoint, and just augmenting the
           | existing one for a screen. Which would cause them to
           | accumulate dead data over time (especially if multiple app
           | versions had to be supported concurrently -- in the case of
           | Facebook this was ~3000 versions).
           | 
           | 3. Being lazy and finding a similar endpoint meant for
           | another use case and piggy-backing it for your new usage.
           | 
           | All of these would create maintenance and organisational
           | problems.
           | 
           | GraphQL is essentially a system that lets you write endpoint
           | specs (in the form of GraphQL query documents) that the
           | backend knows how to support. It's not a free lunch, you
           | still have to do a lot of work on the backend to allow it to
           | do this efficiently and securely (nowhere near as difficult
           | as people make it out to be though), but it does a really
           | good job at solving the endpoint maintenance problem.
        
           | itake wrote:
           | You can still design an immutable REST api to match the
           | client's needs. Apollo has really nice out-of-the-box caching
           | that can be tricky to replicate with rest.
           | 
           | I see your point about reducing network requests (graphql
           | lets you co-mingle mutations and queries), but I don't think
           | that feature is used often enough, b/c what if one query
           | fails, then everyone has to fail).
        
             | troupo wrote:
             | > Apollo has really nice out-of-the-box caching that can be
             | tricky to replicate with rest.
             | 
             | Caching is _trivial_ to do with REST.
             | 
             | The "really nice caching" that Apollo does literally
             | deserializes and deep inspects _both_ the request _and_ the
             | response to try and figure out caching on specific fields.
             | Also, POST requests are not cacheable according to HTTP
             | spec.
             | 
             | With REST you set an ETag and/or Cache-Control headers and
             | let your existing infra and client browsers handle that.
        
             | evangow wrote:
             | You can make a REST endpoint match a client's needs, but if
             | you have multiple clients (for example, 1 for mobile and 1
             | for desktop) that all need different amounts of data (for
             | example, the mobile client shows a simplified view with
             | less data), then you would need to write 2 different REST
             | endpoints to handle each clients. Multiply that by the
             | number of pages with a difference.
        
               | troupo wrote:
               | > then you would need to write 2 different REST endpoints
               | to handle each clients.
               | 
               | Or you use Accept header for its intended purpose
               | 
               | Accept: com.company.user-aggregated/json
               | 
               | Accept: com.company.user-aggregated-lite/json
               | 
               | etc.
               | 
               | And let the server return the fields defined by the
               | relevant schemas.
               | 
               | I mean, the advise given for GraphQL in prod is to
               | literally call predefined queries only.
        
           | troupo wrote:
           | > but the N+1 SQL query problem is a giant thorn.
           | 
           | It's worse because in a big system this becomes N+1 API calls
           | to other systems (each with their own permissions, latencies,
           | caching etc.)
        
         | devmor wrote:
         | For an API that centers around filters and nested subfilters to
         | retrieve exponentially specific data, graphql can end up saving
         | you a lot of work.
         | 
         | For anything else, it seems pointless.
        
       | valenterry wrote:
       | I have a lot of experience with GraphQL and I love it. It saves a
       | ton of development time.
       | 
       | However, for those who wonder what the disadvantages are, here
       | are some. They are from real world production experience and they
       | are _not_ what people usually claim wrongly (like graphql would
       | be harder to secure /version, ...)
       | 
       | No, some real pain points are:
       | 
       | 1. Lack of a Map-type. There is no native type to return a
       | list/array of objects but not a map with unique keys or even a
       | set instead of a list. You can fallback to "convention" or custom
       | types (like plain json) but it sucks.
       | 
       | 2. Uploading big files (in chunks) is much more tricky than
       | expected
       | 
       | 3. There are union-types for the returned data. For example, I
       | can query for an animal and get either a cat _or_ a dolphin and
       | if I use typescript or another capable language then the compiler
       | will tell me that. But I cannot _send_ such a request to the
       | server, saying  "here I send you an animal, the data is this
       | ...". The server will have to provide a separate query/endpoint
       | per animal. Very very annoying.
       | 
       | 4. While graphql is awesome when it comes to batching requests,
       | what it is not so awesome at is to improve performance by
       | allowing the server to return the part of the data is already
       | resolved. So while reducing the number http requests, now the
       | previous slowest http request will become the bottleneck for all.
       | This means the page might load subjectively faster because some
       | parts are rendered later than possible. There is work going on
       | here (like @defer) but it's not fully spec'd and also the
       | solution doesn't work for some cases
       | 
       | There are more points but this gives you some idea of the ACTUAL
       | problems. Otherwise, from development and setup time over
       | maintenance, analytics, versioning/deprecation, tooling and so
       | on, graphql is much better than your standard REST api in my
       | opinion.
        
         | scotty79 wrote:
         | > Lack of a Map-type.
         | 
         | Why do you need special map types for transferring maps?
         | Doesn't list of key-value pairs suffice?
         | 
         | Also, why am I wrong to even ask the above questions?
        
           | valenterry wrote:
           | It's a fair question. Having a map-type has several benefits:
           | 
           | 1. I can signal to my api's users that there won't be any
           | repeating keys without having to write documentation
           | 
           | 2. The type can be mapped correctly into the target language.
           | Most languages have a map-type and so it's nice if you don't
           | have to convert it yourself
           | 
           | 3. No manual conversion also saves time in most cases, since
           | libraries can do it efficiently in one step. Otherwise you
           | get a list<X> from your library and have to turn it into a
           | map. Not good for bigger lists in performance sensitive
           | applications
           | 
           | 4. The same is also true the other way around when sending
           | data to the server
           | 
           | 5. It saves space in many serialization formats like json.
           | Instead of [{"key": "key1", value: "value1"}, ...] you get
           | {"key1": "value1", ...}
           | 
           | 6. It's nicer to read and debug
           | 
           | 7. It's nicer to manually create/write those values in tools
           | like graphiql to test queries by hand and those tools can
           | even warn you if you repeat a key by accident
           | 
           | Just some of the things out of my head, I'm sure I've missed
           | a bunch.
        
           | tadfisher wrote:
           | A (single-level) Map is generally understood to have unique
           | keys, which allows for some invariants derived from this
           | property, such as a one-to-one or one-to-many object
           | relationship, without runtime checks in client code.
           | 
           | I do think it's worthwhile to ask the question, though. I
           | have a strong personal preference to avoid encoding
           | invariants like this in wire representations, because they
           | are properties of the _schema_ and not the wire type (JSON
           | object, in my most commonly-encountered case).
           | 
           | Of course, the entire point of GraphQL is to encode
           | invariants in the data schema, so it's entirely reasonable to
           | ask for a built-in Map type instead of building your own for
           | every project.
        
       | sibeliuss wrote:
       | Definitely not working anywhere that doesn't have a GraphQL api.
       | Once you've used it at scale there's no going back.
        
         | runeks wrote:
         | Go on...
        
       | x86x87 wrote:
       | I never understood why people go for graphql.
       | 
       | In my experience, it's a nightmare to 1/ secure 2/ version 3/
       | ensure qos
       | 
       | Securing it properly should make it a no-go in like 95% of cases.
       | you get amazing flexibility on the front end with a heavy heavy
       | cost on the backend. Also, in general being able to say "i want
       | to do whatever" and request everything at once is an anti-pattern
       | IMHO, especially after HTTP2 became mainstream and doing multiple
       | requests is reasonably fast.
       | 
       | Versioning? Forget about it. Now you have "all the versions" and
       | good luck figuring out what is used, what is not used or god
       | forbid deprecate something. you're going to have a bad time.
       | 
       | As far as qos goes, if any client can range from "i'm asking a
       | simple thing" to "i would like the whole world please - and btw
       | you're only going to figure things out as you pull them in" qos
       | becomes a pipe dream.
       | 
       | Last, I don't understand what Netflix does that is so complex
       | that would warrant something like gql. I just don't. To the naive
       | developer in me it seems that they 1) need to have a basic api to
       | get whatever catalog they have + a few apps build on top of that
       | 2) have figured out how to do streaming exceptionally well in
       | order to scale to all the people watching. That's is and although
       | a gross oversimplification I cannot think about a scenario where
       | gql is needed.
       | 
       | I think in their desire to reinvent the wheel Netflix has jumped
       | the shark. A lot of really good ideas have come out of the
       | innovation they did in the past but lately it seems like they are
       | doing things for the sake of doing them or they are pissing
       | people off with password household policies and whatnot.
        
         | jdauriemma wrote:
         | The state of the art of GraphQL tooling around securing and
         | versioning has evolved significantly. You may want to take
         | another look at what's out there.
        
           | rblatz wrote:
           | I was just researching graphql versioning and the
           | recommendation is not to version because the graph is
           | supposed to be an evolving entity.
        
             | x86x87 wrote:
             | [flagged]
        
               | Dudester230602 wrote:
               | Put this into the _" my code is self-documenting"_ bin.
        
               | x86x87 wrote:
               | my self-documenting code is evolving!
        
             | itsmeste wrote:
             | mutation createUser-v2
             | 
             | Seen that in some productive APIs, always fun.
        
           | tnzk wrote:
           | Could you please provide some pointers?
        
         | thrashh wrote:
         | GraphQL is like SQL. It's an extremely leaky abstraction but in
         | the hands of someone experienced, you can do amazing things
         | with a fraction of the effort required.
         | 
         | But just like SQL, you have people who happened to learn SQL in
         | passing and it's like a table saw in the hands of someone who
         | doesn't know what to do.
        
         | geodel wrote:
         | Netflix is large company with huge IT/software workforce. And
         | as I have seem in large companies tech managers and engineers
         | don't usually keep waiting for actual problem to appear and
         | develop solution for it. They are going to take initiative to
         | migrate _legacy monolith_ to next generation micro services,
         | GraphQL architecture and in process save their jobs.
        
           | x86x87 wrote:
           | The timing of this is hilarious. Here is something that's on
           | the front page at the same time:
           | https://news.ycombinator.com/item?id=36380711
        
         | downWidOutaFite wrote:
         | My main issue with it is client-side caching doesn't map
         | cleanly to graphql. I want well-defined objects to cache.
        
           | gareve wrote:
           | that's solved with Relay's graphstore
        
         | sibeliuss wrote:
         | It's 2023. There are _so many tools and patterns now_.
        
           | x86x87 wrote:
           | [flagged]
        
         | devjab wrote:
         | Have you tried the alternatives? We went with Odata, and it's
         | hell. It's fine on the client side, but it's terrible to work
         | with on the server-side. We went down the C# path because
         | everyone else is either using RPC or GraphQL, but even
         | Microsofts own libaries don't work together. The model creatirs
         | for Odata and Entity Framework sort of work the same, but are
         | also different enough to cause some real annoyances and once
         | you add asp.versioning it becomes even worse. We went with
         | Odata because we had a hefty client that consumed Odata through
         | a client library that we build ourselves, and at the time it
         | seemed like it would be fine. A year later it turns out that it
         | would've been better for us to rewrite everything to work with
         | GraphQL, and, we may actually end up doing that eventually
         | because the Odata .NET support is so terrible that we're
         | constantly having to rewrite parts of it to get it do things
         | that are trivial in GraphQL.
         | 
         | You can of course go other routes, we took a serius look at
         | tRPC, but it seemed like it would end up being a lot of work.
         | Actually quite similar to how doing the things you want from a
         | frontend perspective is a lot of work if your backend is "just"
         | rest.
         | 
         | > Last, I don't understand what Netflix does that is so complex
         | that would warrant something like gql. I just don't.
         | 
         | If you dig into the other blog points that the OP link to you
         | can see that it's because they needed better performance, more
         | security and better control of the flow. I think you may
         | underestimate how much you get for "free" when using graphQL.
         | It has so much adoption, that there are so many tools that you
         | won't have to build from scracth, even if you're Netflix. You
         | can see our Odata library as an example of this, there are
         | client libraries that we could've used, but they're bad. So we
         | had to build our own. With GraphQL we wouldn't need to do that.
        
           | x86x87 wrote:
           | IMHO, Rest works just fine. If you are serious about
           | performance I don't really get how you do that with GQL.
           | maybe I'm just ignorant but the apps I've worked on were
           | medium to large size and it was a fricking nightmare (apollo-
           | based, a couple of years back).
           | 
           | Here:
           | 
           | https://hackerone.com/hacktivity?querystring=graphql&filter=.
           | ..
        
             | valenterry wrote:
             | I think it's simple. You can get the best performance with
             | REST, but you have to really put lots of resources into it.
             | 
             | On the other hand, with constraint resources, you likely
             | end up with better performance when using graphql because
             | of the reduction of requests and decreased latency.
             | 
             | In most cases, graphql hits the sweet spot.
        
         | buro9 wrote:
         | > I never understood why people go for graphql.
         | 
         | It allows a full separation of the frontend dev velocity from
         | the backend velocity.
         | 
         | The frontend is no longer dependant on backend engineers for
         | API creation, nor negotiations on how those should look.
         | 
         | The backend can choose to observe the hot path of GraphQL and
         | optimise those for your #3, but #1 and #2 don't differ from,
         | say, REST.
        
           | physicsguy wrote:
           | Except when it's not performant, and then suddenly you need
           | those backend guys again!
        
           | x86x87 wrote:
           | So you're solving an organizational problem by using gql? Who
           | needs proper authz/authn, security, scalability, sanity, qos
           | if we can have frontend dev velocity? Checks out.
        
             | pests wrote:
             | Don't we solve organizational problems with software all
             | the time?
             | 
             | Git Monorepo vs Polyrepo Microservices vs Monolith
             | Kubernetes
        
             | dasil003 wrote:
             | > _So you 're solving an organizational problem by using
             | gql?_
             | 
             | Yes, of course! All problems are organizational problems at
             | scale. I have no great love for gql, but painting it as a
             | black and white decision pitting FE velocity against all
             | other engineering concerns (including hyperbole like
             | "sanity") is childish. There are legit tradeoffs
             | discussions to be had, but if you think it's impossible to
             | secure or scale gql then you're not a very imaginative or
             | resourceful engineer.
        
             | seanp2k2 wrote:
             | GraphQL really needs a gateway like Envoy to give better
             | observability / control / auth, and indeed that's how lots
             | of people deploy it.
        
               | politelemon wrote:
               | Is it not possible without Envoy? IMO this feels like a
               | failing if I'm relying on a separate piece of software.
               | I'm comparing it with RESTish services which are easily
               | scaleable in many ways either software or infra. But that
               | might be my misunderstanding of what you just said
        
               | x86x87 wrote:
               | Okay. Tell me how you do the control/auth and allow
               | certain users to access a resource while others do not
               | access it while they may formulate complex queries where
               | they ask for the kitchen sink.
        
               | pravus wrote:
               | I honestly don't understand the complaints here. In our
               | deployment it's implemented as an HTTP handler right next
               | to all the REST ones and gets all of the standard
               | authz/authn/obervability wrappers. It's allowed us to
               | focus more on core development because the schema was
               | exported over a year ago and hasn't changed much. It
               | functions almost identically to the REST components but
               | is easier to develop against. No issues with scale or
               | performance that aren't apparent in the REST components
               | either.
        
               | tomtheelder wrote:
               | Honestly there's a few good ways to do that. Schema
               | directives, regular old permission system at the resolver
               | level, etc.
               | 
               | I'm not a big fan of GraphQL, but I it's not particularly
               | difficult to secure.
        
               | andrewingram wrote:
               | By wrapping the code that loads data with code that
               | checks whether the current (i.e. requesting) user is
               | allowed to load that data. I don't really understand the
               | problem, how is this any more difficult than any other
               | API paradigm?
        
               | foota wrote:
               | I think the additional issues come when you want to
               | define access by a relationship instead of just the
               | entity, which means you need to check access based on the
               | edges, and not the nodes. You'd have to do this anyway
               | with REST, but I think it's easier in some ways to make
               | mistakes and allow more access than intended.
        
             | eddythompson80 wrote:
             | Solving organizational problems is a core component of any
             | software you design in any organization that's not a 100%
             | flat startup unfortunately.
             | 
             | > "Any organization that designs a system (defined broadly)
             | will produce a design whose structure is a copy of the
             | organization's communication structure." - Melvin E. Conway
             | 
             | It's unavoidable. You can bury your head in the sand about
             | it and demand that the technical structure only match your
             | technical requirement, but then the organizational
             | structure of the company will grind to a hault. People will
             | always be people. Just because you give some of them a
             | title like "Engineer" doesn't mean that we won't conflict
             | on people problems.
             | 
             | Entire concepts like event driven architectures or
             | microservices, while might have plethora of technical
             | pros/cons are mainly pushed by management for their non-
             | technical aspects. One of their main non-technical pro is
             | organizational. If your component just emits events,
             | handles events, and is implemented as a separate
             | microservice then you can always just insert a team, or
             | move a team in an organizational structure while minimizing
             | the overall impact to a project.
        
           | jameshart wrote:
           | > frontend is no longer dependant on backend engineers for
           | API creation
           | 
           | So long as the backend engineers at least anticipated all the
           | relationships, properties and objects that the frontend might
           | ever need?
        
         | dan-robertson wrote:
         | I feel like this is a bad take: I'm not sure what your
         | experience with graphql is but your comments about Netflix
         | strike me as naive. I think there is a simplified version of
         | Netflix that doesn't do eg recommendation or history or
         | different contracts in different countries and so on, which is
         | maybe just a few api calls, but I don't think that's what
         | Netflix is. And are they actually reinventing the wheel here? I
         | thought graphql was a Facebook thing. Maybe you meant to say
         | that they are rewriting systems pointlessly but it (also) feels
         | like a bit of a generic criticism that is easy to apply to
         | companies for which in-house systems make sense.
         | 
         | (Edit: it's not even like this is a graphql vs rest change as
         | Netflix have had graphql for years and they have a custom api
         | system that seems a lot more like graphql than it does rest)
         | 
         | I'm curious what you think the best advantages of graphql are,
         | particularly for a larger company like Netflix?
         | 
         | I would guess:
         | 
         | - reduces coordination/contention between different
         | frontend/backend teams (eg there are many clients - desktop,
         | mobile, various smart devices - but maybe other front ends too
         | like something customer support might use).
         | 
         | - cuts down on 'boilerplate' api work. For example, maybe you
         | have some property X of each item Y in your catalog, but which
         | you don't get on the request for the catalog, and that you want
         | to display this now (maybe it's some new experimental feature
         | you need to thread through from some database table to the
         | front end). You need to choose between adding X to the catalog
         | (potential version woes...) or managing a bunch of requests for
         | X for each Y (risks being slow or bad in a few ways), or add
         | some non-restful api endpoint that takes a list of Ys and gives
         | you their X properties. With graphql you need to teach the
         | backend how to get X of Y but the frontend only needs to change
         | the query.
         | 
         | - it potentially lets you apply access controls in a more
         | straightforward way. If someone is from the US, maybe there are
         | some shows they can't see. In that case we probably want to
         | hide all records in results about shows they can't see.
         | (Alternative example: various properties of other people's
         | accounts). If you have many separate api endpoints, it feels
         | easier to me to accidentally screw up on one of them.
         | 
         | I'm not really very familiar with graphql but the middle option
         | is the most compelling one for some of the things I work on
         | (which are nothing like Netflix). One assumes that some people
         | from Netflix had reasons for graphql and I'm interested in what
         | they were rather than some imagined Venn diagram with the
         | current api in the 'not invented here' area and graphql in the
         | intersection of 'invented here' and 'not yet a thing we have'.
         | I'd also be curious to see how well it works out for them over
         | time - perhaps they'll regret it but maybe not for the reasons
         | you oppose graphql; if there are organisational problems (like
         | some team becoming a big new bottleneck or some teams being
         | unhappy about it being 'forced on them'), they can be hard to
         | write about.
        
         | pmoriarty wrote:
         | GraphQL is such complete and utter garbage for anything but the
         | simplest of queries. I pity anyone who has to use it for
         | anything more complicated.
        
           | x86x87 wrote:
           | i would not go as far as saying complete and utter garbage,
           | but it 95% of cases it brings with it a can of worms that you
           | don't need and don't want. All in the name of "frontend
           | developer velocity"!
        
         | hn_throwaway_99 wrote:
         | Going to reply here because, as a huge fan of GraphQL, I
         | strongly disagree with every single one of your points. To
         | start, I think the biggest misconception I see about the value
         | of GraphQL is people see it as some sort of generic "query
         | language", which is unsurprising, given the name. If anything I
         | think the biggest problem with GraphQL is that, if people just
         | saw it is a simple alternative to REST, with a well defined set
         | of query (GET) and mutation (PUT/POST/DELETE) endpoints, they
         | wouldn't get caught up in all this "infinite object graph"
         | stuff that I never hit in my day-to-day.
         | 
         | To your points:
         | 
         | 1. I find GraphQL to be _fantastic_ for security, primarily
         | because all calls are strongly typed, so you can ensure by the
         | time a request gets to your resolver it is guaranteed to match
         | the defined input types. Furthermore, I always make heavy use
         | of custom scalar types instead of String, which allows me to
         | get rid of a whole host of potential security issues by
         | limiting potential injection attacks before my code even sees
         | it. As far as ensuring object ownership /permissions, this is
         | trivially easy, or in any case just as easy as with REST.
         | 
         | 2. Versioning is one of GraphQL's greatest strengths. The
         | tooling makes it easy to deprecate some fields while adding
         | replacement ones in a way that guarantees backwards
         | compatibility. Far from "good luck figuring out what is used",
         | the tooling e.g. in Apollo makes it very easy to see which
         | clients are making use of which fields. Furthermore, if you do
         | need to "hard version" a new endpoint, you can do it similarly
         | to REST by including a version parameter in your URL (e.g.
         | /v1/myGraphQLEndpoint).
         | 
         | 3. Regarding qos, this again just gets to my original point
         | about having well defined queries and mutations. Your queries
         | don't need to say "allow me to see the world" any more than any
         | other API framework. It's not hard to just have queries that
         | only say "give me X by ID" and also a single bulk retrieval
         | endpoint where you define the boundaries of what you want to
         | return.
         | 
         | If anything, I think perhaps a lot of misconceptions around the
         | problems of GraphQL have to do with these tools that basically
         | say "expose my whole DB with GraphQL", which in my experience
         | usually leads to tears in the end.
         | 
         | But starting with a thoughtful definition of your API surface
         | area with GraphQL's type definition language can make it a joy
         | to use and provides lots of benefits over a straight RESTful
         | interface.
        
           | politelemon wrote:
           | If I'm understanding correctly, there is a lot more work a
           | team has to do to build and maintain a GraphQL API and should
           | only do it if they understand what they're getting into and
           | what its advantages are. It's not for everyone, and everyone
           | shouldn't assume it's for them.
        
             | hn_throwaway_99 wrote:
             | > there is a lot more work a team has to do to build and
             | maintain a GraphQL API
             | 
             | I wouldn't say that. It's simple and straightforward to get
             | around some pitfalls of GraphQL, if you treat it as an
             | enumerated set of RPC-style endpoints.
             | 
             | The commenter I was replying to stated "Thr fact that
             | you're arguing that it should not be treated as a generic
             | query language when it's in the name and this is how it's
             | sold is hilaruous". Perhaps so. _By far_ the biggest
             | mistake I think the original designers of GraphQL made was
             | putting  "QL" in the name, as many people think it's in the
             | same category of tools as SQL (I heard someone ask once on
             | HN "Can you do joins in GraphQL?", which isn't even a
             | question that makes sense). It should be treated as a
             | competitor to OpenAPI, and there are reasons why I would
             | prefer using GraphQL in many scenarios.
             | 
             | I think I'll probably write some longer form blog posts at
             | some point about how I think GraphQL is easy to set up and
             | get running quickly, and how to avoid some common
             | misconceptions.
        
               | troupo wrote:
               | > It's simple and straightforward to get around some
               | pitfalls of GraphQL
               | 
               | It isn't
               | 
               | > if you treat it as an enumerated set of RPC-style
               | endpoints.
               | 
               | It's not that.
               | 
               | > I think the original designers of GraphQL made was
               | putting "QL" in the name, as many people think it's in
               | the same category of tools as SQL
               | 
               | "GraphQL is a query language for APIs" is literally the
               | tagline at https://graphql.org/
               | 
               | And the frankly insane complexity of GraphQL comes from
               | the fact that you now have to implement that query
               | language, often over completely different sources of
               | data.
               | 
               | Which leads to frankly inane solutions like the
               | requirement to inspect the full request _and_ the full
               | response on the fly just to be able to cache responses.
        
               | [deleted]
        
           | x86x87 wrote:
           | [flagged]
        
             | runeks wrote:
             | > Falling back to arguing about typing show me that maybe
             | you are not aware of the many interseting ways you can get
             | screwed or maybe you just worked on simple straightforward
             | things.
             | 
             | Please provide a few examples of this.
        
               | x86x87 wrote:
               | Since I'm not going to type a novel here is an example: h
               | ttps://wundergraph.com/blog/the_complete_graphql_security
               | _g...
               | 
               | Also look at hackerone:
               | 
               | https://hackerone.com/hacktivity?querystring=graphql
        
             | zeroxfe wrote:
             | > So in conclusion, you're moving the goalposts and
             | asserting that everyone that has issues with the tech must
             | be an idiot since it works for you.
             | 
             | That's not what GP asserted at all. You made some vague
             | statements about gql, and they refuted with very concrete
             | arguments.
        
             | hn_throwaway_99 wrote:
             | I didn't call anyone else an idiot. You don't actually seem
             | to be open to hear about how people can use GraphQL, in
             | production, to solve a host of thorny issues that "plain
             | REST" APIs commonly have to deal with. Congrats on your
             | intellectual superiority.
        
           | dcre wrote:
           | This is helpful, but it confirms my sense that a REST API
           | with a typed spec like OpenAPI is going to get you basically
           | all the benefits of GraphQL.
        
             | magic_quotes wrote:
             | Pretty much, they are fundamentally both RPC flavors, so
             | it's impossible for them to have different properties
             | beyond more or less convenient tooling. It's always jarring
             | to see those heated GraphQL vs REST APIs (as implemented in
             | practice) vs gRPC discussions as if they are as different
             | as, say, client-side CRDTs.
        
           | jakubmazanec wrote:
           | > if people just saw it is a simple alternative to REST, with
           | a well defined set of query (GET) and mutation
           | (PUT/POST/DELETE) endpoints, they wouldn't get caught up in
           | all this "infinite object graph" stuff that I never hit in my
           | day-to-day.
           | 
           | Can you explain this more? How can you avoid infinite graphs?
           | If I have User {things: Thing[]} and Thing {owner: User}, you
           | have to deal with this issue.
        
             | vinnymac wrote:
             | I have been writing GraphQL APIs on and off for the last 5
             | years, and in practice haven't had a scenario where this
             | was an issue.
             | 
             | In GraphQL the query for the example you gave could look
             | like this
             | 
             | ```gql query { user { things { owner { id } } } } ```
             | 
             | When resolving an array of type `Thing` for the `things`
             | field, you would query for the user that the `owner` field
             | represents. Rather than assuming all relations should be
             | loaded for an owner by default, the client would specify
             | the fields for the `owner` that it needs. Such as I have
             | above for the owner id. Even if no fields are specified, it
             | would be weird to assume all relations should be loaded by
             | default.
             | 
             | Now if your developers are intentionally creating
             | infinitely deep queries, then you'd solve this the same way
             | you'd solve an infinite loop in your code today. An issue
             | you would catch during development or CI/CD. This can be
             | easy to catch using a linter or during review.
             | 
             | ```gql query { user { things { owner { things { owner {
             | things { } # etc } } } } } } ```
             | 
             | To simply protect from bad parties / developers, you might
             | use something like https://github.com/slicknode/graphql-
             | query-complexity
             | 
             | In addition you could introduce CI tools to enforce your
             | devs stop writing such complex queries. Also see the @skip
             | and @include directives that can further be used to control
             | what data is queried. In practice, however, this isn't
             | something that comes up too much. In cases where I have
             | seen this happen, it's usually because a developer is
             | trying to reuse fragments without considering what data
             | they are querying, and whether they should be reusing those
             | fragments.
             | 
             | https://graphql.org/learn/queries/#fragments
        
           | Philip-J-Fry wrote:
           | >If anything I think the biggest problem with GraphQL is
           | that, if people just saw it is a simple alternative to REST,
           | with a well defined set of query (GET) and mutation
           | (PUT/POST/DELETE) endpoints, they wouldn't get caught up in
           | all this "infinite object graph" stuff that I never hit in my
           | day-to-day.
           | 
           | But isn't this "infinite object graph" like the only real
           | valuable part of GraphQL? People get caught up on that
           | because all the other things you mention aren't really an
           | issue with normal REST API.
           | 
           | If you're saying you use GraphQL but don't use the key
           | defining feature of GraphQL. Then what's the point of using
           | GraphQL if you're just using a strict predefined set of
           | things you can query/mutate?
        
             | scotty79 wrote:
             | Value of GraphQL imho is the ability for the api to be
             | driven by frontend requirements without bothering the
             | backend guys "to expose that one field in that one query".
             | 
             | Once the app is developed I think you might put up
             | reasonable general limits to what queries are responded to
             | in a general manner over the whole api.
        
               | Hippocrates wrote:
               | This is how I have interpreted its value, and frontend
               | devs have very plainly advocated for its use with this
               | argument. I think this is a really silly value prop.
               | 
               | Behind the elegance of a query language that lets you get
               | your perfect little payload, there is a complex server
               | that could need to resolve and block on requests to
               | multiple backends, touch different caches and databases,
               | and do joins and sorts and projections. Front end devs
               | will add the videoRating field and have no idea that this
               | comes from a separate API and causes the response time to
               | double.
               | 
               | Developing some gragantuan do-it-all meta API as a
               | sandbox for frontend engineers is a terrible idea. You
               | don't just slap a graph over your APIs and call it done.
               | The GraphQL server is orders of magnitude more complex
               | than a purpose-built API.
               | 
               | Ultimately once the FE devs have crafted their query to
               | satisfaction it will hardly ever change. It's better to
               | work together and decide whats needed and how to best get
               | that data to your app.
               | 
               | I really favor collaboration on purpose built APIs than
               | gargantuan do-it-all systems.
        
               | swyx wrote:
               | > Ultimately once the FE devs have crafted their query to
               | satisfaction it will hardly ever change
               | 
               | this makes the fallacy that it is FE devs driving change.
               | it is not. it is product management. and to them (and
               | indirectly to you), making it easy to make performant
               | changes without 3 committee meetings is a Good Thing
        
               | jameshart wrote:
               | So this completely contradicts your GP post who says the
               | fact that it supports generic queries is _not_ the point
               | of GraphQL.
               | 
               | So which is it?
        
               | OJFord wrote:
               | So you move the issue to the resolver instead? IMO
               | graphql is trying to allow the frontend to be the
               | 'driver', the first bit; otherwise you just have the
               | backend publish an API and then that is what it is, if
               | that one field is available from a different endpoint
               | than the one you're currently using, that's the one you
               | need to hit (as well), tough.
               | 
               | Not to say either way around is inherently better, I just
               | see it as a switch from backend-driven to frontend-
               | driven.
               | 
               | (Personally I'd love to use something like OpenAPI, with
               | tooling more mature than probably exists, to be properly
               | _schema_ -driven, with both backend and frontend
               | stubs/clients derived from that.)
        
               | scotty79 wrote:
               | > So you move the issue to the resolver instead?
               | 
               | Yes. Where it can be logged, inspected and dealt with
               | wholesale.
               | 
               | It's moveing a problem from intra-team verbal
               | communication into software where it can be dealt with
               | more efficiently with software tools and methods.
               | 
               | > Not to say either way around is inherently better, I
               | just see it as a switch from backend-driven to frontend-
               | driven.
               | 
               | Yes. I think that's the whole point and main benefit of
               | GraphQL which makes a lot of sense since apps that evolve
               | through their development usually have most changes UI
               | driven.
        
               | OJFord wrote:
               | > Where it can be logged, inspected and dealt with
               | wholesale.
               | 
               | Just as it could be in the backend? I don't follow that
               | point.
               | 
               | > apps that evolve through their development usually have
               | most changes UI driven.
               | 
               | That's a fair point certainly, but isn't completely
               | generalisable - if you offer a third-party API at all (or
               | think you might) then maybe don't special-case your own
               | frontend.
        
         | 8note wrote:
         | How does http2 skip the speed of light to speed up sequential
         | requests?
         | 
         | Isn't the back and forth across the network the big problem?
        
         | Rapzid wrote:
         | I hate integrating with public GraphQL APIs as well. Give me a
         | REST API pls for the love of god. It makes me sad GitHub's new
         | projects API is GraphQL-Only.
        
         | bbbbzzz1 wrote:
         | In Apollo server you can add directives to your scehma for
         | authz. It's dead simple.
         | 
         | I'm surprised how so many HN posts about graphql just slander
         | it. If you go to the website and look at the use case of why it
         | was made, it makes it pretty clear when it could be a good to
         | use. My experience with it has been very straight forward and a
         | joy
        
           | withinboredom wrote:
           | GraphQL (as in the language spec) offers no way to perform
           | authz. Just because there are non-standardized extensions out
           | there for some languages, doesn't mean it is available in
           | whatever language you're using.
        
             | tomtheelder wrote:
             | Ok, but that's true whether or not you use GQL.
        
               | withinboredom wrote:
               | Sure. I could respond with a 4xx code because you're not
               | authorized for that field. Ah, but maybe you want to know
               | which field? Too bad GQL doesn't really support that.
        
               | cameronh90 wrote:
               | Authorization errors can go in the errors array which has
               | a path reference in the standard.
               | 
               | You generally don't want to use HTTP error codes with
               | field level errors in GQL.
        
           | x86x87 wrote:
           | [flagged]
        
             | theturtletalks wrote:
             | My SaaS backend is a GraphQL Server that has single-
             | handedly saved me tons of hours for integrations and
             | coding. The first iteration of the app was using rest and
             | that was a pain. Hitting multiple endpoints to get all the
             | details of an order is not something I miss. On top of
             | that, I get a beautiful playground that acts as a query
             | builder and documentation.
             | 
             | Have you actually used GraphQL in production or for a wide-
             | scale project? A lot of these criticisms for GraphQL comes
             | from people who have played with it for an hour and
             | determined it's not good. Give it a real chance and you'll
             | see why big companies are using it and understand why the
             | ecosystem is growing so fast.
        
             | bbbbzzz1 wrote:
             | Feel free to read how to do it
             | 
             | https://www.apollographql.com/docs/apollo-
             | server/schema/dire...
        
         | xwowsersx wrote:
         | Kong seems to have some offerings on the API gateway security
         | front for GraphQL https://konghq.com/blog/engineering/graphql-
         | authorization-at... I haven't looked at it very closely yet,
         | but I'm wondering Kong for other reasons (unrelated to GQL)
        
       | cmgriffing wrote:
       | I think the important thing for people to recognize is that
       | Falcor, the tool used in their mobile apps, was already GraphQL-
       | like. So, this isn't a giant change.
        
       | jFriedensreich wrote:
       | This is a sad but expected day. For years i seem to have been the
       | last lonely falcor user who is still excited about this and
       | thinks this is one of the best abstractions for a key class of
       | state management applications, that are not a great fit to
       | graphQL at all.
       | 
       | - Falcor can be schemaless with optional json schema where it
       | makes sense
       | 
       | - Falcor supports simpler to reason about and implement features
       | that map perfectly to javascript objects so you can do zero
       | boilerplate databinding with ES proxies without writing query and
       | mutation wrappers
       | 
       | - Does not try to be a qyery language but only expose things you
       | need to request the data that needs to be rendered in the UI
       | 
       | I think not even the creators of falcor fully understood how
       | perfect it is if you just add in the last missing piece of fully
       | automating the connection from the falcor model to the place in
       | the UI templates where the data is needed. Most people tried
       | doing this manually in component boilderplate which lead
       | initially to preloading tens of json paths eg
       | falcor.preload([`todos.done.length`,`todos.done[0..10].name`,
       | `todos.done[0..10].date`, ...etc.])
       | 
       | and then people developing GraphQl like syntax for these eg.
       | somthing like                   load(`          todos { done
       | 0...10 {name, data} }  etc.         `)
       | 
       | at which point devs thought they might as well be using graphQL
       | and get more features
       | 
       | The key mistake was that you need to instead think about your UI
       | components ITSELF as the data quueries eg you can automatically
       | derive all falcor quieries from a component like this without ANY
       | boilerplate, and this is only possible with falcor, as everything
       | else has so many features that it would not be possible to map
       | the UI code to the intended data queries                   {#each
       | todos as todo}            <div>{todo.name} ({todo.date})</div>
       | {/each}
       | 
       | It does not look like netflix will hand over falcor to a
       | community and the codebase needs lots of work especially around
       | tooling and overuse of some patterns like a custom observable
       | implementation but i am still on the fence about building a new
       | minimal derived library or forking
        
       | CSDude wrote:
       | Maybe now GraphQL api can stop auto completing movies that does
       | not exist in their catalog.
        
         | paulddraper wrote:
         | ?
         | 
         | It autocompletes so you find out more quickly that Netflix
         | doesn't carry it, and what similar options are
         | 
         | I get that you are annoyed Netflix didn't have the movie you
         | wanted, but autocomplete doesn't make that worse.
        
           | 9dev wrote:
           | You're right, but it's annoying for sure. Instead of telling
           | me they don't have a title, they complete its full name (as
           | if to say ,,I know what you want, but I'm not gonna give it
           | to ya"), yet show me some arbitrary stuff named similar.
           | 
           | It's just a poor solution.
        
       ___________________________________________________________________
       (page generated 2023-06-18 23:00 UTC)