9 ms·
Is GraphQL the Next Frontier for Web APIs?
- dboreham 10y agoYes it probably is. Back when I worked on LDAP, we found that people were using the protocol in unexpected ways, basically as a standardized general purpose record/field/value/query access protocol. They were doing this quite strange thing because it appeared to them better than the alternatives which were : use the underlying database access protocol (usually proprietary and undocumented) or roll their own HTTP-based thing, inventing most of the rules and encoding mechanisms themselves (sound familiar??), or use some invented-by-committee thing such as CORBA. GrahpQL I think is meeting a similar need but with the added advantage that it was designed for the task at hand, mostly not by a committee.
- brandur 10y ago> GraphQL I think is meeting a similar need but with the added advantage that it was designed for the task at hand, mostly not by a committee. Right on. I think that its early strength of opinion and design and having a spec available from the get-go is one of GraphQL's big strengths. There are lots of ideas about how to use REST and HTTP correctly, but for the most part the only things that are universally agreed on are that URLs are _usually_ resources (you can find lots of cases where they're not even in APIs that are popularly thought to be well designed) and that HTTP verbs _should_ map to CRUD (but again, they often don't because ideas like `PATCH` only became widespread quite late in the game).
- JBReefer 10y agoNah, the next frontier is more likely everyone fully consolidating around REST as it stands today. This looks like movement for movement's sake, instead of improving developer ergonomics in an increasingly predictable world. This is like everyone finally agreed on a plug type, and someone starts to push 3 phase. Let's get all the houses wired up, instead.
- chewchew 10y agoHave you ever actually used it? It does greatly improve developer ergonomics on the client side. Check out Apollo + React (or another framework).
- zimablue 10y agoI don't know enough to justify my opinion but I really really don't get REST. Having recently had to learn a lot of web stack in a short time REST was one of the most confusing parts, and I think it's because it intrinsically doesn't make sense. I have a client and a server, they need to share a language so that the client can tell the server what do do. REST seems like jumping from that situation to a situation where you have an object hierarchy modelled as a tree and can only perform CRUD. But why? As in the article, what if I have operations which only make sense as a combination of CRUDs on different objects? What if my type system doesn't map nicely to a tree? Why am I forcing this interface through a step of serializing it into a set of actions that it doesn't naturally map to and don't individually make sense? In most programming languages you import a library with a set of functions or classes, and call them with parameters (binding on key-value or order or both). If the server is to my client side another library, why do I impose CRUD on every operation and pretend that this makes sense? It's like a programming language where instead of calling a function, you have four modes of calling a function which must map to CRUD, (these have different conventions for the same thing (body vs querystring)) although there are no guarantees that they actually do map to CRUD lots of people don't follow the convention properly and everyone insists that you must try to adhere to it as purely as possible in the name of "standardization".
- dragonwriter 10y ago> REST seems like jumping from that situation to a situation where you have an object hierarchy modelled as a tree and can only perform CRUD. But why? Because, frankly, most people doing "REST" don't understand REST. While URLs can imply a tree structure, REST does not give URLs any meaning besides resource identifiers; relations are communicated in resource representations not URLs and can be any model you like. There is a sense in which operations are essentially CRUD-like but, in the database analogy, it's CRUD operations against views with arbitrarily complex definitions, and trigger logic for operations other than reads, not CRUD against base tables. > As in the article, what if I have operations which only make sense as a combination of CRUDs on different objects? Then, most likely, you have a resource for the operation, which you create to initiate the operation (or create to configure and have a specified update to trigger.) > What if my type system doesn't map nicely to a tree? Then you don't use a tree representation REST doesn't need URLs as anything other thab opaque identifiers and resource representations can communicate any relationship structure you want. > If the server is to my client side another library, why do I impose CRUD on every operation and pretend that this makes sense? Well, one, CRUD against resources with unconstrained definitions is part fairly flexible and universal model, so it probably makes sense as long as you don't artificially constrain the model, and second, REST isn't always the right choice anyway. There is nothing wrong with doing RPC or other non-REST things (and it would be better if we could accept that so people could stop feeling obligated to say that the non-REST things they are doing are "REST" and muddying the waters.)
- brandur 10y agoIt's probably not super popular to suggest that REST isn't the be-all and end-all when it comes to web APIs, but I'm interested in a future that lets us integrate with APIs more quickly and more safely. I'm interested to hear about what people think about the subject. (I'm the author.)
- daurnimator 10y agoI'm a big fan of postgrest (https://github.com/begriffs/postgrest/ https://github.com/begriffs/postgrest/). It creates a RESTful HTTP API out of your existing postgres schema. It practically eliminates the need to write a CRUD backend.
- ruslan_talpa 10y agoUsually when you say CRUD people tend to think "limited functionality" and PostgREST is a bit more then "basic CRUD" as i am sure you know. It's interface is powerful enough to support GraphQL on top (since this is the topic of this thread :) https://subzero.cloud/ https://subzero.cloud/ )
- brandur 10y agoYes, PostgREST is awesome :) It turns out that most of what is usually expressed in implementation code assuming that you're hitting a dumb backend is just as well-served by SQL functions and schemas. This probably breaks down for larger projects, but it certainly has its place, and I can imagine something very similar be done for GraphQL.
- ruslan_talpa 10y agoI don't think it breaks down (as long as most of the data comes form the database). For example i know exactly how paymoapp.com (similar to basecamp) is structured , i consider it to be a fairly large system and i know for a fact that PostgREST can support that. As for the "very similar be done for GraphQL", there is https://github.com/postgraphql/postgraphql https://github.com/postgraphql/postgraphql which was based on postgrest ideas. Another approach would be to build graphql on top of postgrest (my comment below)
- mehaveaccount 10y agoOur front end guys use it at work. They seem excited about it. It actually makes a lot of sense to me, but I haven't used it myself except for their quick star wars demo when it was first announced.
- daliwali 10y agoBy Betteridge's Law of Headlines, the answer is "No". REST describes the architecture of the web, which most websites already conform to. Developers could design web APIs more like web pages, but standard media types must be adopted first. JSON-LD is a strong contender at that.
- brandur 10y ago> By Betteridge's Law of Headlines, the answer is "No". I feel a little bad for phrasing a title like a question, but an alternative working title was "The Future of API Paradigms". I tried to touch on a variety of possible paths beyond GraphQL, including that REST might be the right way forward. > REST describes the architecture of the web, which most websites already conform to. Developers could design web APIs more like web pages, but standard media types must be adopted first. JSON-LD is a strong contender at that. Yes, quite possible, but it seems to me that REST and hypermedia aren't actually buying us all that much when it comes to APIs. Theoretically it makes them more discoverable and future proof, but in practice I find that no one really uses these features, and even when they're available, they're often used improperly. On the other hand, something like GraphQL has some pretty significant advantages in the form of very flexible querying and very efficient message transport (you get everything in one call instead of _N_).
- daliwali 10y agoHaving a specification that tells you exactly how to do a particular thing can be more expedient than being open to interpretation. But short-term benefits aren't exactly a goal of REST: >REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly opposed to short-term efficiency. Unfortunately, people are fairly good at short-term design, and usually awful at long-term design. Most don’t think they need to design past the current release. [0] There isn't anything about REST that is opposed to flexible querying or fetching multiple resources in one request. Isn't that what web pages do already? I've used very complicated search forms and fetched lots of related data on the same page. What makes it possible is the use of standards like query strings, x-www-urlformencoded, multipart/formdata, and HTML itself. Machine clients may just need their own media types. [0] http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-724 http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte...
- agumonkey 10y agoClojurescripters liked to leverage GraphQL (david nolen)
- jraines 10y agoMore as an inspiration, though. You don't have to define a spec with om.next queries, for example. Walmart Labs just released a library about a week ago that does actual GraphQL, and there are libraries for the front-end but they aren't widely adopted and not really like Relay, afaik
- gbog 10y agoI don't know for web external APIs but for an internal network of services talking to each other I've found GraphQL to be very convenient. The "single entry point" and "describe what you want, you'll get what you described" mindset makes it powerful, when used with the graphiql trial and error interface. We barely have to document anything anymore. It seems a bit weird to use a twisted json for the queries but it works well after getting used to it. If someone wants to go this road, I'd suggest enforcing use of variables in queries (so high level caching works better) and do directly to the connection modelfor pagination. http://graphql.org/learn/queries/#variables http://graphql.org/learn/queries/#variables http://graphql.org/learn/pagination/ http://graphql.org/learn/pagination/
- brandur 10y ago> The "single entry point" and "describe what you want, you'll get what you described" mindset makes it powerful, when used with the graphiql trial and error interface. We barely have to document anything anymore. +1. It seems to me that another big advantage is speed of implementation. No matter how good your web stack is, implementing a whole bunch of separate HTTP endpoints tends to be fairly verbose and slow, and each should probably be tested thoroughly in separate modules. GraphQL mostly involves mapping data available in the GraphQL API to how it should be fetched in the backend. Lots of huge opportunities for sharing and reusing code, which is especially good for internal work where you don't necessarily need all the bells and whistles.
- lioeters 10y agoPersonally, I found the description of (G)RPC intriguing, since the API that I've been building recently for a project resembles this most closely. I had started by trying to follow REST, then over time in an effort to reduce and simplify network requests, the API became a collection of, basically, remote function calls - organized as a map of "actions" on both client and server. I'm still pretty much a novice at building APIs, though, so the article was educational for me to compare the pros and cons of various approaches.
- daxfohl 10y agoREST is horrible. It encourages new developers to think in terms of CRUD, which is also horrible. (https://msdn.microsoft.com/en-us/library/ms978509.aspx https://msdn.microsoft.com/en-us/library/ms978509.aspx). RPC is great. It encourages developers to think in terms of functions and leverage more creative ways of getting things done. Event Sourcing, CQRS, etc. GraphQL is really neither here nor there. It's more of a convention on top of those layers. I think it's a good idea, and a good convention for libraries in different languages to rally around. Though it can be abused too: don't use it to replace a fairly simple set of REST-style queries just because you can. Is GraphQL the future? It may be part of it. But, it's not everything. It's just a query language. Okay there's a mutation part of the spec too, and it's CRUD-like. I'd like GraphQL better if there was a more RPC-like mutation. I hope the future includes some more interesting streaming-style protocols. The whole request/response thing is pretty boring anymore no matter how you do it.
- Exuma 10y agoI have a fairly dumb question. If one were building a standard web app... say, a super simple web store that lists products, allows someone to submit products and such. How would they use RPC instead of rest? Can you give some concrete examples of how it's different / better.
- bigmanwalter 10y agoIt's more natural to deal with collections and other data structures using RPC. REST works best with single items. As soon as you need to start generating reports, it can be complicated to create sane REST endpoints whereas it's trivial with RPC. REST: GET /api/item/1 GET /api/item/2 POST /api/item { name: foo, collection: 1 } POST /api/item { name: bar, collection: 1 } RPC: GET /api/items POST /api/items [{ name: foo, collection: 1 }, { name: bar, collection: 1 }]
- njharman 10y agoHow are your RPC examples not REST? RPC would involve client lib. And may or may not even use HTTP as transport. api.get_product(id=1) api.add_product(details)
- anon1253 10y agoWe tried to use GraphQL, but it in our opinion it has a major design flaw: not everything that can be expressed in JSON can be expressed in GraphQL. Since our application makes heavy use of Semantic Web (if you haven't already, checkout SPARQL and RDF which made similar promises). But this means we often end up with responses that contain URIs as map keys. This is not allowed as a filter in GraphQL, even though it is valid JSON. Other parts of our stack contain Clojure(Script), and we make use of namespaced keywords that serialize to "foo/bar" as map keys. Again something that is not allowed in the language, and would break our application. I find it a particularly odd design choice to not make GraphQL spec match the JSON spec. As there are now many things that are impossible to specify as a query, which would otherwise be valid JSON.
- brandur 10y ago> I find it a particularly odd design choice to not make GraphQL spec match the JSON spec. I can't speak for the original authors, but I can kind of understand it just by virtue of the fact that JSON is quite an ugly format that's hard to write for humans and comes with plenty of opportunity for error (missing quotes in places and the like). Their language also allows the introduction of some higher level semantics like an `Int!` to indicate that an argument can't be null. Finally, GraphQL's query language has one major feature that makes it worth alone: you can comment things! This is something that you could never hope to do in JSON :/
- anon1253 10y agoOh I totally agree there. I never quite grokked the obsession with JSON these days. But if you go to trouble of writing a query language that /specifically/ targets JSON output ... it seems like it would at least need to be comprehensive. Or come up with another output serializer/deserializer ... but that would put considerable strain on the consumers.
- cryptica 10y agoI can see three contenders: 1. CRDTs/sync solutions (like Firebase) 2. GraphQL with real-time subscriptions 3. A variant of REST over WebSockets with real-time subscriptions I don't think #1 will be able to cover all necessary use cases because it is much more computationally expensive (in terms of memory, CPU and bandwidth). Both #2 and #3 are good solutions but I think #3 will prevail in the end because it's a lot simpler. You can break-up RESTful resources into individual fields which each have their own independent real-time subscriptions (so each observable model on the front end can hold a single property of a resource). With GraphQL, you may end up with overlapping fields between different 'views' and it makes it harder to track/manage subscriptions.
- FractalNerve 10y agoThis list is very interesting! Which one performs the best in: • Raw Performance • Proven Architecture • Robustness & Congestion Tolerance • Backward & forward compatibility • Customizability Is ASN.1 by Fabrice Bellard the fastest serialization format? http://bellard.org/ffasn1/ http://bellard.org/ffasn1/ Here's a lits of all formats: https://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats https://en.wikipedia.org/wiki/Comparison_of_data_serializati...
- jondubois 10y agoGraphQL and REST solutions will almost certainly be much faster than any CRDT solution. I think that the REST solution should be more efficient than the GraphQL solution but it probably won't be a drastic difference. The essence of the REST philosophy is to deal with data as small atomic building blocks - I think that this is one of the most important and well-tested ideas in software engineering so on that basis, I would go with REST. Though you could also argue that the idea of querying (which is what GraphQL essentially is) is also well tested. CRDTs are bad with bandwidth and they require very heavy/complex clients that are difficult to implement - Once implemented, they make life easier for many use cases but take away flexibility and customizability. I think the main challenge with GraphQL actually might be doing access control on the back-end. If you have a GraphQL query that fetches many different resource types, it's a lot more difficult to establish whether or not a user is allowed to access all these resources at once (GraphQL approach) vs just a single resource at a time (REST Approach). With GraphQL you may have to deal with partial access rights - where the user is only allowed to see part of the query's result. With REST, each request can only have a single allowed/blocked response.
- daxfohl 10y agoFunny thing is GraphQL isn't a graph query language. It returns lists. I'm working on a similar concept for a project right now, but that actually queries graphs / trees. (Sorry, not open source). As I've been working on this, it's struck me as odd how much query technology is built around tables and how hard it is to fit graphs and trees into it with reasonable performance.
- anon1253 10y agoAren't you afraid you might be reinventing SPARQL ;-) ?
- throwaway2016a 10y agoI'm a major REST advocate (spoken at conferences, written about it in books, etc) and I've been using GraphQL for a few months now and after an initial learning curve I love the flexibility. But in my opinion, the answer is: write code once, expose both interfaces. Here's what I mean... I've been writing my APIs as GraphQL first. Then putting a very light wrapper around GraphQL to expose a REST interface. The REST interface is gold standard (HATEOAS, Json-API, etc) yet it is only a few lines of code. I just have a dictionary of REST -> GraphQL mappings and transform the GraphQL result to Json-API. Then I also expose the GraphQL interface. So users that want to use GraphQL can. It's a win-win and it didn't take me any more time to develop than just REST. As an added bonus, the GraphQL code is inherently easier to unit test by nature. GraphQL has a lot of flaws (for one it has nothing to do with graphs -- nearest I can tell the name is only because it was first used for Facebooks graph database) and things like pagination and error handling have no standard way to do them. But it is very flexible.
- brandur 10y ago> I'm a major REST advocate (spoken at conferences, written about it in books, etc) and I've been using GraphQL for a few months now and after an initial learning curve I love the flexibility. It's good to hear that there are some REST people that are open to potential alternatives :) > I've been writing my APIs as GraphQL first. Then putting a very light wrapper around GraphQL to expose a REST interface. The REST interface is gold standard (HATEOAS, Json-API, etc) yet it is only a few lines of code. I just have a dictionary of REST -> GraphQL mappings and transform the GraphQL result to Json-API. I'd certainly agree there. This could change in a year or two, but right now REST-ish APIs are still indisputably dominant. If you want to maximize your developers' experience, it's still too early to _require_ that they use GraphQL because there are going to be a lot of shops out there that are just not set up for it. Of course there is still the option of providing your own libraries and tooling for your users to go through, and if you go with that then the API's implementation is much less important.
- ruslan_talpa 10y agoIf the answer is: "expose both interfaces" then my implementation is exactly it :) GraphQL & REST API for your database (https://subzero.cloud/ https://subzero.cloud/) At the core sits PostgREST (https://postgrest.com/ https://postgrest.com/)
- awinder 10y ago"Roy Fielding’s original ideas around REST are elegant and now quite widespread" I don't think this is actually true. I think you see some ideas plucked from Fielding's paper, but describing REST in terms of performing CRUD on resources is not what Fielding's paper is largely about. There's some good RESTful APIs out there, and Stripe does have a pretty nice API for the current state of API affairs. But I'd say we're still decently early in figuring out how to more widely leverage concepts from Fielding's paper, so declaring that REST isn't fulfilling needs seems a little short to me. I'd rather see what happens if more people commit to understanding & implementing other beneficial concepts in their APIs. "REST also has other problems. Resource payloads can be quite large because they return everything instead of just what you need, and in many cases they don’t map well to the kind of information that clients actually want, forcing expensive N + 1 query situations." So maybe the idea here is that it's harder to implement, but you can absolutely structure REST APIs to have these same benefits, and actually you may find it to offer benefits over graphql here. There is nothing un-REST-like about returning different message formats based on the client sending you a specified request header, or providing a url parameter, or what have you. You can actually leverage this to you (& your API client's benefit) by providing a small subset of different response "shapes", or you could just allow them to specify exactly what they need for a request in a free-for-all sort of fashion. It's all up to you, but I can't buy this argument for GraphQL, it's a symptom of writing inflexible REST-ish APIs, not a damning fact of REST as a concept.
- marwanad 10y agoGraphQL was not meant to be a replacement for REST. It doesn't seem to right to compare an architectural concept to a query language. The main power of GraphQL is for client developers and lies in the decoupling it provides between the client and server and the ability to fulfill the client needs in a single round trip. This is great for mobile devices with slower networks. Introspection is a really powerful tool and you can build tools around that to do compile time checks and automatically generate class definitions based on your schema.
- jaequery 10y agorpc looks to be the most flexible of the bunch. what are the downsides of rpc approach as compared to rest and graphql?
- otto_ortega 10y agoDoes anyone knows if there is a REST variant that allows to send/get associated resources nested on a single call? Taking the customers+charges example on the article, something like: POST /api/customers/null/charges { name: 'John Cash', dob: '1990-01-01', charges:[ {type:1, amount: 12.5}, {type:1, amount: 22.8} ] } I think the option to bundle things on a single call is wonderful, but GraphSQL seems much more complicated to implement than REST.
- throwaway2016a 10y ago> Does anyone knows if there is a REST variant that allows to send/get associated resources nested on a single call? Json API has standards for how to do related records. http://jsonapi.org/format/#fetching-includes http://jsonapi.org/format/#fetching-includes > I think the option to bundle things on a single call is wonderful, but GraphSQL seems much more complicated to implement than REST. Not necessarily. I find GraphQL easier to write and consume but harder to handle errors and pagination. Plus caching is impossible in GraphQL without client-side special code. But I use node.js which has avery mature GraphQL library. If there isn't a library for your language it would be very difficult. If done properly there are actually a lot of rules to doing REST. For example, that JSON you put is not REST because it doesn't have Hypermedia. Of course, REST has the benefit of requiring no external libraries except HTTP. And no one says you have to follow all the constraints of REST (though I recommend it).
- otto_ortega 10y agoAwesome, seems like the "JSON API" specification is the REST-ish API variant I was looking for. It has support for "related resources" and even "sparse fieldsets" (http://jsonapi.org/format/#fetching-sparse-fieldsets http://jsonapi.org/format/#fetching-sparse-fieldsets) which covers the main advantages I can see on GraphQL in reducing number of request and the size of the responses.
- tantan 10y agoI Kaltura.com we auto generate all client libraries in all different coding languages based on auto-generated API descriptor XML that generated using reflection from the server code. It solves most compilation, maintenance and usability issues for integrators. See our clients generator: https://github.com/kaltura/clients-generator https://github.com/kaltura/clients-generator See few more server side examples: https://restafar.com/ https://restafar.com/
- tantan 10y agoI Kaltura.com we auto generate all client libraries in all different coding languages based on auto-generated API descriptor XML that generated using reflection from the server code. It solves most compilation, maintenance and usability issues for integrators. See our clients generator: https://github.com/kaltura/clients-generator https://github.com/kaltura/clients-generator See few more server side examples: https://restafar.com/ https://restafar.com/