9 ms·
I tried applying GraphQL to standard webapp/services projects, and could not get really far. Maybe I'm missing something, help is appreciated. GraphQL lets con
by jeswin 10y ago
I tried applying GraphQL to standard webapp/services projects, and could not get really far. Maybe I'm missing something, help is appreciated.
GraphQL lets consumers (Web UIs, Mobile Apps etc) define the shape of data they want to receive from a backend service. Theoretically, this is awesome since at the time of writing the backend service you don't always know which fields and relationships a consumer might require. The problem arrives when you add security. There are plenty of things that a client is not supposed to see, often based on the roles of the requesting user. That means that you can't pass a GraphQL query directly to an underlying DB provider without verifying what is being requested. You'd end up writing about the same amount of code that you'd have written with a standard REST-style (or other) interface.
I also considered using it for Server to DB data fetches, where my backend Web Service would request an underlying GraphQL aware driver for some data. I did not find it particularly more expressive than using SQL or using an ORM.
One good thing about GraphQL is that it sort of formalises the schema and the relationship between entities. You could perform validations on incoming query parameters and mutations. It also helps clients understand the underlying schema and would serve as excellent documentation. This might be useful, but a REST API also offers some level of intuitiveness, and ORMs (especially in strongly-typed languages) offer some level of parameter and query validation.
These are probably early days, but it'd be nice to see some real world use cases for GraphQL which lie right in the middle of simple todo-list type of apps, and the unique needs of FaceBook.
- friedman23 10y ago> There are plenty of things that a client is not supposed to see, often based on the roles of the requesting user. That means that you can't pass a GraphQL query directly to an underlying DB provider without verifying what is being requested. You'd end up writing about the same amount of code that you'd have written with a standard REST-style interface. Why would you need to write the same amount of code? The only code that would remain the same is the validation logic.
- untog 10y agoPerhaps another way of asking it: how is GraphQL different to sending SQL statements from the client? In both scenarios you'd be "only" handling validation logic and ignoring the rest.
- tscs37 10y agoNot much difference except that GraphQL does not specify how the data is processed. You could answer the data out of a flatfile for all that the endpoint cares. It also allows to secure access against arbitrary data requests, since on the server end, the resources only see the individual requests to the DB. In my experience, it's much easier and less verbose to validate GraphQL after parsing than just validating any SQL you plan to pass to the backend.
- jordanthoms 10y agoThe amount of code needed to verify that only the proper fields and records are included for a particular response taking into account the user's permissions etc is often not so different from the code needed to retrieve just that data in the first place. There is an issue here where as you give more sophisticated querying capabilities to the client, you need to have correspondingly more sophisticated validation of those queries on the server, which offsets some of the gain.
- maratd 10y ago> You'd end up writing about the same amount of code that you'd have written with a standard REST-style interface. With every fad that has hit backend development, ORM/move-everything-to-frontend/merge frontend and backend a la Meteor/GraphQL/etc, there have been promises of simplicity and less code. The problem, as you discovered, is that the overwhelming majority of non-CRUD code on the backend is directly related to security and cannot be abstracted away or moved anywhere else. You end up dancing the same dance, no matter what paradigm you use and some of them make that dance a bit more awkward. Personally, I've settled on Swagger a few years back. There's no fancy paradigm, it's just plain REST with an open sec. Because you define your API ahead of time, you can automate CRUD, automate validation, testing, and documentation. All that's left is the nitty-gritty which you have to do no matter what and it doesn't have an opinion on how that should be done, that part is up to you.
- ruslan_talpa 10y agoit can be moved, to the database itself (constraints, grants)
- ht85 10y agoI've written an interface similar to GraphQL some time before it was made public using JSON to describe the desired data tree, filters, etc. The real upside of GraphQL is that it has become popular enough that there are parsers in most languages, and that you don't waste time designing and testing a new standard. If you use it for a public API, you can also simply point people to the existing documentation. It's definitely not a widely accepted standard, but still better than rolling your own!
- untog 10y agoA question from someone that has never used GraphQL: what makes it better than SQL? You don't even need parsers in different languages for SQL, you could just send it straight to the DB. But I assume I'm missing something.
- RussianCow 10y ago> You don't even need parsers in different languages for SQL, you could just send it straight to the DB. You probably don't want to do that for security reasons. So either way you need a parser, and at that point, it makes sense to use something that is database agnostic and allows you to model relationships without complex joins or otherwise exposing the internal representation of the data.
- vcarl 10y agoClients can use it to request exactly what they need. Since it's a graph, you can just keep grabbing nodes to get the fields you need in the shape that works for your client. GitHub added a GraphQL endpoint for their API, the improvements they cited were reduced overfetching of data the client didn't use e.g. urls to linked resources, and fewer underfetches e.g. using the results of the first request to populate a second or third request. http://githubengineering.com/the-github-graphql-api/ http://githubengineering.com/the-github-graphql-api/ It's not really GraphQL vs SQL, it's GraphQL vs RESTful APIs.
- ht85 10y agoYou might be confused by how PostGraphQL works, as it makes the queries very close to the database structure. In real life there will usually be a lot more going on to serve a GraphQL query than simply translating it to SQL. The data you'll send might come from many different sources, including any kind of database, caches, or just constants in your code. As commented here, permissions over data is a big topic, and if you were accepting raw SQL, you'd have to parse / tokenize it, and somehow validate it before executing it. This is what GraphQL does, but instead of trimming down and restricting the usage of SQL, it defines a language that is similar, close to being a subset of it, with a much simpler syntax.
- nine_k 10y agoWriting the same amount of code is OK. Doing one round-trip instead of several, no matter how deep and complicated your data tree is, may be the interesting part.
- mikerybka 10y agoThat can easily be achieved by not following REST so strictly.
- zten 10y agoNaming and formatting it differently is an easy way to get away from the REST dogma, though.
- nine_k 10y agoVerily! GraphQL is one way to do just that. REST has the virtues of uniformity and discoverability. I don't yet understand whether GraphQL possesses any of these too, though.
- ec109685 10y agoCan you provide standardized examples of REST's uniforms toy and discoverability?
- debaserab2 10y agohttps://spring.io/understanding/HATEOAS https://spring.io/understanding/HATEOAS
- dkersten 10y agoIts worth nothing that Roy Fielding, the guy who coined the term REST, doesn't consider an API RESTful unless it implements HATEOAS. At least, that's what he said in some talk I watched sometime ago.
- paulddraper 10y agoThe point isn't to write less code -- especially server-side code. The point is to provide a consistent, feature-rich, declarative, verifiable and performant API that is easy for the client to develop against. SQL is an excellent analog -- no, it doesn't make the SQL server implementation easy, but it's a consistent, declarative, and powerful API. "Even" business analysts can write SQL queries. If you don't have a strong incentive to make life easy for the client, the case for GraphQL isn't as strong.
- jeswin 10y agoGraphQL works really well for some edge cases, and those edge cases will be more evident if you're FaceBook. For smaller projects, the benefits of integrating GraphQL libraries on the client and the server v/s special handling for a limited set of APIs is not obvious. By special handling, I meant: https://example.com/friends?fields=name,pic,posts&posts_len=10 The vast majority of APIs will not require this kind of result-shaping. And for those that do, passing comma separated fields (using a protocol teams already understand) is worth trying before adopting something more drastic. Of course, YMMV.
- chacham15 10y agoOften what gets lost in these kinds of discussions is the difference between what is theoretical and what is practical. Yes, you can have a perfectly designed REST API which has all of these features. What happens, though, when you want a new piece of data? Do you redesign the API to fit this new piece of information into it or do you make a new endpoint? What if the new piece of data doesnt actually belong with `friends` but if you do the fetch for friends and this new piece of data at the same time you can get a performance boost? Do you make a new endpoint `friendsandfamily`? Now, what if you want to migrate all calls over to that endpoint, you now need to figure out if any of your frontend code or legacy systems are still using that old endpoint before you remove it. The maintenance of that system is much higher because you've conflated what data you want with how you want to get it.
- riffraff 10y ago
- sirtaj 10y ago> That means that you can't pass a GraphQL query directly to an underlying DB provider without verifying what is being requested. You'd end up writing about the same amount of code that you'd have written with a standard REST-style (or other) interface. One benefit of committing to PostgreSQL as a backend: It already supplies a rich set of features for fine-grained security, and with views it's easily possible to add the filtering features. This can reduce the need for much of the app middleware that does this traditionally. This is the thinking behind PostgREST, for example.
- mvindahl 10y agoI've seen access control implemented both at database level (views and stored procedures) and at middleware level (Java/Hibernate). I'll greatly recommend the first of the two approaches, even if it means that developers have to deal with SQL and of the PL of the database. Thing is, they need to know this stuff anyway to be worth their pay. Hiding behind an ORM gives you this nice, familiar, and deceiving feeling of data just being objects which you can manipulate pretty much for free. I've seen many examples of code which load up the entire contents of tables, then proceed to manipulate it in clunky Java. Scales terribly, of course.
- codesnik 10y agoHm, I'm curious. How do you implement database level access control for the generic case of website with hundreds of thousands users? Do you suggest, given a postgres database for example, to add the same amount of roles, and to have individual db connections initiated per each request?
- mvindahl 10y agoHmm.. may depend upon the granularity that you need I guess. As far as I recall, databases do implement access control at table level, but often you need better control than that. In the system that I most recently worked on we had to implement our own access control logic as table level was too coarse. It was a datacenter management system which supported multiple users, each with a set of roles, and each user belonging to several companies. The data center inventory that would be returned by queries depended both upon your role (sysadm vs customer admin vs regular Joe) and upon your company affiliation. I guess I'm mostly writing this to illustrate how quickly this kind of thing becomes closely intertangled with the domain and with your business logic. Will try to answer your questions to the best of my ability: 1) The amount of users is not a scalability issue but the number of requests may be, of course. I'll assume that's what you mean. My best advice would be to profile your system to see how it behaves at great load. If access control turns out to be a problem, maybe you are doing too complex joins. One path forward may be to "denormalize" your database scheme, i.e. accept that the same information is stored in several places for the sake of efficiency. Another idea is to spin up an Elastic Search box to help with the query that is your #1 bottleneck. 2) As for the question about individual database connections, well, I think I'd pool them or I would build upon some framework or app server which pools them. It's an easy win with standardized solutions. Caveat: Bear in mind that although I seem to be posing as some kind of expert right now, I'm really not. I'm more of an all-round full stack kind of guy. So seek advice from multiple sources :)
- fulafel 10y agoAnyone know if colleagues of GraphQL address this somehow? Like Falcor, om.next, Datomic, DataScript, Relay, Neo4j etc? (I know some of those might not be the same, just throwing in a bunch of names vaguely clustered in my head)
- jerven 10y agoSPARQL, the W3C standard real Graph QL, where most implementations accept queries direct over http. Have implementations that do role based security depending on the connection. Commercial implementations such as StarDog or Oracle Semantic Network among many others, will allow you to limit certain subsets of your data in many ways, and connect to many other datasources via different translators/mappers. For the JSON developer though you would need to combine it with a nice JSON-LD formater which is not yet common among implementations.
- unixhero 10y agoComments like these. This is why I read Hacker News
- eknkc 10y agoWe have an app running on graphql with 3 different user roles. I'm not sure what other people do but on field resolvers we check for the current users access level and see if they should be seeing this thing. If not, the resolvers return errors. In a more elegant approach, we have some of our object types duplicated / inherited. Say, "User" and "UserAdminView". If an admin queries user(id:3) they receive "UserAdminView". If a user does that, they receive a watered down "User" type, which exposes only the fields users can see. UI then selects the appropriate fragment. Maybe there are much better ways though.
- sametmax 10y agoFor me the main benefit of graphql is to have a common interface for mixed backends. One query seems unified, while it may request data from an SQL DB, the cache, redis, the file system, elastic search, etc. It makes it very easy to switch backends, or reuse the same query on the client or the server. Microservices have one common standard language to query data, to whatever it wants. ORMs tried to do that but they work well only for relational data. Plus unless you use JS everywhere, you can use it on the client and the server.
- Matthias247 10y agoI also built a prototype with it. IMHO the best feature is strongly typed data and introspection, which enables lots of tools (like GraphiQL). But you can build something like this for traditional RPC APIs too - that's not necessarily related to the other GraphQL features. The next advantage is of course letting the client define what he wants to retrieve in a single query. Whether this is useful depends on your application I think. For mine - while it was cool to use - it had no big benefit compared to having a set of orthogonal RPC APIs that the client could use to fetch the information it needs. Less round trips are a reason, but if you have your API on HTTP/2 or something else which supports small queries efficiently it might not have a too large impact. The other large difference is that with a "lots of small APIs" approach you have to compose the data on the client while with GraphQL it's done on the server. One advantage of doing it on the server makes the load of it more predictable, since the complexity of the queries is well known and there can't be clients which try to issue queries with an abnormal amount of complexity. What I disliked most about GraphQL were mutations. The ability to include multiple mutations into a request made it sometimes hard to reason about which of those succeed or errored based on the query result. I also don't see a huge benefit of specifying a complex query result for a mutation - as I am also now one of the believers that queries should be separated from mutations/commands and that the mutation mostly needs to report back whether an operation succeeded. So all in all I now think it is an interesting operation for a Query API, if the target application requires complex user-defined queries. But I would rather not use it if clients mostly query the same amount of data or for command/control APIs.
- floatboth 10y agoYou can compose data on the server without GraphQL. PostgREST does this (ironically not very "RESTful") thing: http://postgrest.com/api/reading/#embedding-foreign-entities http://postgrest.com/api/reading/#embedding-foreign-entities
- iso-8859-1 10y agoWould it be possible to write the server part such that either all mutations succeed, or none of them do?
- regularfry 10y agoIt's useful for unifying upstream providers. If all you're doing is using it to pretend the server-side application layer doesn't need to exist, it's going hurt.
- leonardinius 10y agoIt might be something already mentioned below here, on mobile so might miss it. However, what we do : we use PG role row level access. E.g. each database user has explicitly defined the subset of data ih has access to. All you need to ensure your application business level views do not mix/confuse logical view of partial data. And! You choose to use correct database user in your back-end data stream/feed. Have I already mentioned the PG is a great tool and the feature gap between MS Sql, Oracle and PG constantly narrows down as we speak? _Edit_ typos & errors
- user5994461 10y ago> I tried applying GraphQL to standard webapp/services projects I'm sorry I don't understand. Graphs are not a thing for running webapps/services. They are a subset of CS/maths aimed to solve specifics problems that can be expressed as graphs. If you don't have a graph problem to solve, you don't need a graph database.
- wolfgang42 10y agoGraphQL is a bit of a misnomer, it's not actually for querying mathematical graphs. It's so named because it was originally for https://graph.facebook.com https://graph.facebook.com
- ntoshev 10y agoMy understanding is that different user roles would see different schemas depending on what they are allowed to see. This should definitely reduce the amount of code that needs to be written. I haven't actually implemented such an API though, so I may be wrong.