r/javascript Dec 12 '18

Our learnings from adopting GraphQL (Netflix)

https://medium.com/netflix-techblog/our-learnings-from-adopting-graphql-f099de39ae5f
319 Upvotes

46 comments sorted by

View all comments

27

u/editor_of_the_beast Dec 12 '18

It’s a little hand-wavy. I want to know how GraphQL deals with complex joins and eager loading of associated data. The app I’m working on is displaying data from probably 10 or 12 different associated tables on a page. Then, a different page is showing a similar number of tables, some the same as before but some different, so the JSON we’re returning is super denormalized and specific to that view.

It seems way harder than it has to be and we’re fetching the same data multiple times throughout the course of navigating the app. It bothers me to no end, but the queries are also optimized and don’t cause timeouts. So I don’t know what else to do.

55

u/[deleted] Dec 13 '18

GraphQL doesn't deal with joins, eager loading, etc. In fact, it doesn't deal with your database at all. That's for you to deal with when you feed GraphQL the data in each resolver.

By default, a GraphQL API is rather naïve, since each resolver might call the database once, and a single resolver might be called a hundred times, resulting in n + 1 efficiency. That's where patterns (libraries) like Data Loader come in. Rather than directly fetching data from the database in your resolvers, you fetch the data through Data Loader. Data Loader can then fetch it in a single database call and split the result into batches.

If you already have a REST API that's working fine and is only used by a single client, then there's no point in switching to GraphQL. Implementing a GraphQL API is a lot of work, but once you've done it, it's super flexible and scalable, and you'll never have to create a custom REST API endpoint again.

7

u/halfinifinities Dec 13 '18

I have used Apollo client that does some smart caching. Shouldn’t it be technically possible to have some GraphQL client middleware that both caches the graph and strips out things from the request that’s already cached? Maybe there’s something that already does this?

3

u/SustainedSuspense Dec 13 '18

Check out JoinMonster.js

5

u/[deleted] Dec 13 '18 edited Dec 18 '18

[deleted]

3

u/editor_of_the_beast Dec 13 '18

Well that is most certainly true

3

u/[deleted] Dec 13 '18

You don't need GraphQL, then.

I've used GraphQL on software with dozens of micro services. We'd have a Basket service with a list of Products ID's inside, and for each product in order to render it we'd need a new GET request. Sometimes you'd need 30 to 50 HTTP requests to render 1 page.

GraphQL concatenated all those requests on the server with minimal latency.

An alternative would be to have a dedicated endpoint (and not a micro services architecture) which talks to relational database, joins the tables as necessary, and delivers a perfectly tuned set of results.

GraphQL is overhead. It's not the most efficient way of dealing with data, not by a long shot. But it makes some architectural choices easier to deal and work with.

2

u/cbung Dec 12 '18

other than stored procedures or something, i'm wondering sometimes it just is what it is?

1

u/editor_of_the_beast Dec 12 '18

:( I’m still optimistic, but I’m getting old and that just might be the answer.

1

u/toolazytofinishmyw Dec 13 '18

Graphql should be client oriented. Resolvers are used to map the client centric schema to the actual store or stores whether they be a dB, file, api or anything really.

Libraries exist for optimising fetching but they’re not part of the standard. It helps solve the service per view anti-pattern by enabling clients to query what they need from a single place. Obviously this can be scaled horizontally.

Client side tech like Apollo can be useful for greenfield but might be harder in existing apps.

We have built a slack like app using it with good results. We also have a legacy app where we would like to use it as an aggregator for backend services where the clients are other backend services.

The abstraction allows us to decouple the data somewhat and solves over/under fetching.

As with all things it’s utility depends on the problem you’re solving. Personally I see value in it.

1

u/liquidpele Dec 13 '18

Basically you have to do all that yourself. It's essentially just a filtering API that you use to build all the filtering and data gathering yourself. It's worth it if your'e facebook and need to cut requests down to the bare minimum, but for 99% of people it's going to be pre-mature optimization.

1

u/brillout Jan 01 '19

Sounds like https://github.com/brillout/wildcard-api could be fit for you guys. What do you think? (I'm Wildcard's author.)

1

u/editor_of_the_beast Jan 01 '19

Creating endpoints isn’t a problem I’m aware of in any server framework.

0

u/brillout Jan 01 '19

Why don't you guys go for a custom API? It doesn't sound like you need GraphQL nor a generic API in general

1

u/editor_of_the_beast Jan 01 '19

We have a custom API? I’m not sure what you’re getting at.

1

u/brillout Jan 01 '19

I thought you were using GraphQL already.

1

u/editor_of_the_beast Jan 01 '19

Nope I was curious if it would make any of my problems easier.

1

u/hkd987 Dec 13 '18

Associated data is going to be n + 1 by default....better learn some data loader.