5 ms·
There's something I never quite understood about GraphQL, and this seems like a good thread to ask! With REST, all my APIs are defined and I can easily test al
by cs-szazz 6y ago
There's something I never quite understood about GraphQL, and this seems like a good thread to ask!
With REST, all my APIs are defined and I can easily test all the database queries my server will run, check that they're indexed, etc. But with GraphQL, my understanding is a client might be able to request something like "Give me all users whose phone number starts with 555". It's possible that query isn't indexed, and after deploying the app we end up tanking our database performance, right? That seems like a huge potential issue to me, but I might be misunderstanding how it works in practice.
- jensneuse 6y agoThis is not an issue from my point of view. If you do GraphQL the right way you'll always use persisted Queries. For each persisted Query you know exactly how it behaves and you can test it before you go to production. WunderGraph uses persisted queries by default. We don't allow arbitrary queries at runtime. Here's a post on the topic if you're interested to dive into this a bit more: https://wundergraph.com/docs/concepts/persisted_queries https://wundergraph.com/docs/concepts/persisted_queries
- barumi 6y ago> This is not an issue from my point of view. If you do GraphQL the right way you'll always use persisted Queries. But that's not using GraphQL "the right way", is it? I mean, GraphQL's value proposition is quite literally letting front-end developers run all sorts of ad-hoc queries without having to bother about indexes, and only care about the data you wish to extract. If all you want is to run fixed queries then you're already better off putting up a REST API.
- diveanon 6y agoFront end developers are api consumers in the same way that a third party client is. As others have stated persistent queries are the answer. You can disable them in local dev if you want to give your devs more flexibility, but I have found it usually isn't necessary.
- jensneuse 6y agoFacebook, the inventors of GraphQL, didn't just invent the language itself. At the same time they invented the Relay client. This client, back then, persisted all Queries at compile time. They never had actual Queries at runtime. It's Apollo with their Apollo client who made it popular to not follow this path. The devs at Facebook never said you must use GraphQL their way but I think if you don't follow their best practices you're kind of on your own. Why not follow their advice? They must have learned this lesson already.
- VWWHFSfQ 6y agoYeah if you have a fixed number of well-known queries that you support then a plain old REST API is superior in pretty much every way
- hnrodey 6y agoYour GraphQL api is capable only of what you code it to do. GraphQL is nothing more than a "contract definition" on what callers can ask your API to do. The responsibility is still totally up to you to determine what database query to run and optimize/index appropriate. Zero difference from your REST call.
- cs-szazz 6y agoI see, so you're saying that the GraphQL contract wouldn't actually allow querying by phone number in the first place?
- leesalminen 6y agoIt’s up to whoever built the backend. GQL doesn’t care either way. If the person who built the back end wanted to allow query by phone number, they’d index that field to maintain query performance.
- jmull3n 6y agoYou don't directly query your database from GraphQL. Similar to REST, you read the parameters from the request and build your database query using the object–relational mapping library of your choice. A popular one at the moment for Node is Prisma.
- cs-szazz 6y agoBut in this imaginary situation, there's no efficient way to query the database without adding an index, and the suggestion is it's harder to know what your clients will call versus REST because one is statically defined while the other is more freeform.
- diveanon 6y agoThis problem is solved at the db layer. If your data is not queryable in an efficient manner from the DB then it doesn't really matter if you use REST or GQL.
- iampims 6y agoIt’s up to the graphql server implementation to resolve queries however it sees fit. In many cases this type of query would be implemented with a cursor, so not all users would be returned at once.
- cs-szazz 6y agoA cursor doesn't really help much if there's no index on our imaginary `users.phone_number` column. But based on another comment, it seems that we'd limit the ability of the clients to query by phone number in the first place?
- throw_m239339 6y agoGraphQL is 2010's SOAP. Whatever happens in the database is not GraphQL concern. GraphQL is just a contract between the client and the server, and a better one than HATEOAS or whatever REST.
- harryf 6y agoThanks for saying that. I haven’t used GraphQL but when I read about it I was like “Isn’t this basically RPC again? Like XML-RPC (for those that remember that) and SOAP?” To me the acid test, since getting burnt by both XML-RPC and SOAP has always been “can I drop a standard HTTP proxy Like nginx between this thing the layer behind or in front to cache reads?” GraphQL _seems_ like you can’t really do that so you end up having to build caching into your app, which in turn - in my experience - always leads to systems you can’t predictably reason about
- true_religion 6y agoYou can cache reads with a HTTP proxy. I know that’s what we are doing at work anyways.
- merrywhether 6y agoYou generally wouldn’t run a cache in front of your GraphQL server, but can definitely have a cache between your data sources and your GraphQL resolvers. For instance, we have a single GraphQL interface in front of many backing micro services. Some of those are very hot and constantly handle direct reads, others only access the backing services through redis reads, others basically do REST requests (which are cached as normal) and drop unrequested fields (basically the BFF pattern from the article), and others even have hybrid approaches where accessing a certain subset of available fields sends you to a cache and accessing others triggers a live read. The resolver architecture gives you a lot of flexibility, but it also can enable a lot of complexity (though it is fairly easy to reason about because all of the connections are explicit). We’re a big org, so we’d have complexity either way, and switching to GraphQL has absolutely been a huge improvement that no one regrets (though we’ve learned a lot along the way).
- lipanski 6y ago> Give me all users whose phone number starts with 555 There's no magic there, it's left up to you whether you expose such functionality and you are in full control of all fields that make up your API. Most of the time your APIs will reflect your database associations `{ users { posts { comments } } }` which should be indexed anyway. Custom queries on top of that, like a search filter, can be indexed/optimized individually. Resources can be paginated quite easily and you can also enforce a maximum depth when requesting associations, so that you don't end up with requests too large to deliver. The main problem with GraphQL comes from the many different ways you can use it, which makes caching or eager loading difficult.
- cs-szazz 6y agoI see, thanks for the explanation! I think a lot of my coworkers think of GraphQL as some magic where it lets the client query for arbitrary things and avoid us having to add query parameters where appropriate, so I never got the whole picture. It sounds like the main benefit over REST isn't so much the queries themselves, but being able to control what data you get back, which is more in line with the article.
- mleo 6y agoYou can use tools that will automatically generate GraphQL schema and operations from a database or it should be you design the schema & operations and control how the queries and mutations operate. The former is where some of the original concerns may come from, but the latter isn’t different from REST design.
- cs-szazz 6y agoThe former would be something like Hasura right? As a backend dev, I get nervous when I see a tagline like "Instant GraphQL APIs for you data", because I worry about the schema and operations that are exposed.
- slow_donkey 6y ago
- sysashi 6y agosorry for stupid question, how REST and database indexes are related?
- diveanon 6y agoThey aren't. There is just a lot of anti-patterns floating around because of tightly coupled API / DB's. People apply this same logic to GQL and get confused.
- cratermoon 6y ago> People apply this same logic to GQL And programmers will apply this same anti-pattern to GQL, so it doesn't really solve that problem, and arguably makes it worse for the reasons stated in the un-indexed field example.
- diveanon 6y agoAnd that is why you used gql codegen and typing to limit their capability to do so. Part of the benefit of gql that people often overlook is its self documenting nature and when tied with automation tools its ability to provide a lot of flexibility for developers without compromising you db. The gql server is ultimately what is responsible for this, and we use schema introspection to ensure the searchable / sortable fields are only exposed if indexed.
- cratermoon 6y agoShould I go back into my archives and look over the number of technologies leaning on code generation and model introspection that failed to catch on?
- cs-szazz 6y agoThey're not really related here. The premise of my question is more around the fact that with REST, which database queries you'll run are fairly static and are known by the backend based on what APIs they expose. Therefore it's easy (ish) to make sure said queries are indexed properly. With GraphQL, I'm asking about how clients _could_ write arbitrary requests, that since the backend doesn't know about them ahead of time, can't optimize for with indexes.
- hirundo 6y agoWe build our GraphQL schema partially by running introspection on our MySQL schema. Only fields that are indexed in MySQL are valid sort/filter parameters in the GraphQL schema. To make a field sort/filter-able we add an index in a MySQL migration and regenerate the GraphQL schema from the new database.
- fizx 6y agoYou can whitelist queries!