(I'm the author.)
* Security; allowing evaluation rather than a describing results.
* DDL; Data Structure and Types need to be learned out-of-band. Ideally we want a sort-of interactive INFORMATION_SCHEMA over http, so our tools can inform us about types/structure and we always have updated info as we write queries.
* Performance; Stored Procedures (server-side) protect against a client making poor joins; ORMs requesting too much data, etc...
* Info about Security: client side SQL doesn't know what rights it has, or you could say that a client account can't see the big picture of DDL. The understanding of rights is all communicated through non-API means.
* Info about Performance: clients don't know rate limits, current system load, what system admins consider reasonable data sizes or reasonable analytic calculations, etc...
I don't know what GraphQL does for each of those issues, but I'd love to hear.
[0] I recently setup InfluxDB which has a (private) web interface that takes raw SQL-ish, and it's so convenient.
So for example, if you allowed "comments" to be queried within a "user", you'd make sure that users could be looked up efficiently by their ID, and that comments could be loaded in bulk efficiently based on user ID. You'd also make sure that your implementation for both those operations is secure.
It's not too dissimilar to REST in that you're still very much designing what your API should look like and not exposing anything else.
It creates a RESTful HTTP API out of your existing postgres schema. It practically eliminates the need to write a CRUD backend.
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.
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.
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.
It can readily convey graph information, e.g. what are the first and last names of the friends of the friends of user 123? But yes, there's nothing really graph specific.
If it bothers you that "Graph Query Language" is too specific, just remember that "Structured Query Language" is too general :)
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.
It encourages developers to think in terms of data, which is amazing. At the end of the day, we're just doing data transformations, that's it. GraphQL is an interesting iteration on that idea, because it focuses more on the data.
REST is simply a way to design your APIs so that they're extensible, usable, and maintainable. If you're doing something really specific, maybe it's not the best thing, but it's a really good starting point.
As per your CQRS comment.... https://martinfowler.com/bliki/CQRS.html
"Despite these benefits, you should be very cautious about using CQRS. Many information systems fit well with the notion of an information base that is updated in the same way that it's read, adding CQRS to such a system can add significant complexity. I've certainly seen cases where it's made a significant drag on productivity, adding an unwarranted amount of risk to the project, even in the hands of a capable team. So while CQRS is a pattern that's good to have in the toolbox, beware that it is difficult to use well and you can easily chop off important bits if you mishandle it."
That's kind of the thing though. REST doesn't do transformations. It just does CRUD of resources.
For me, when designing an application, I will think, "is representational state transfer the only thing this application will ever need to do?" If the answer is "no" then REST seems like a poor model to build around. I've never answered "yes" to that question. (That said, I spent many years mindlessly building REST apps before I started asking myself that).
Per CQRS etc., that's right. It's a tool. Use it when appropriate. Don't use it when not. (That said, the scare factor of that article is a bit high--I've had very little trouble with it since switching to it as my go-to update pattern about five years ago. Also note Martin Fowler has changed his mind on several topics lately, such as the Rich vs Anemic domain model, away from OOP and toward a more FP viewpoint. CQRS is certainly the more FP model here.)
I mean, nothing here can't be worked around. Millions of sites do this just fine. But to me, the mental model just doesn't match up. The REST model tries to present a facade that everything is a "resource". In my experience, as apps get bigger, more and more things start not quite fitting that model. You end up having to justify to yourself why certain things go on certain endpoints and soon half your API is REST and half is some hacky REST-RPC hybrid anyway. Starting with an RPC model from the get-go, you avoid these problems.
And note, REST and RPC aren't technologies. REST is a form of RPC, and you can certainly roll your own RPC protocol over REST. They're merely different ways of thinking about and modeling your application.
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 }]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.
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".
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.)
I certainly agree with the plug idea -- consistency is very good -- but I think that we should really consider what REST is actually buying us at the end of the day.
Most people prefer to integrate through a well-maintained SDK where one is available rather than shelling out to HTTP directly (imagine calling the APIs of something like AWS over raw HTTP), and if that's fairly widespread, it might not be too bad of a thing to start moving the underlying transmission protocol of those SDKs over to something that's more flexible and more efficient (like GraphQL, but also maybe other things).
A comparable analog might be when Google experimented with replacing TCP and TLS with a new protocol called QUIC that operates over UDP [1]. Because QUIC still exposes an HTTP/2 API, providers and server-side infrastructure could potentially move over to it relatively painlessly.
[1] https://ma.ttias.be/googles-quic-protocol-moving-web-tcp-udp...
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.
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/
Here's a lits of all formats: https://en.wikipedia.org/wiki/Comparison_of_data_serializati...
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.
Or a I reading the current status of the RFC[1] wrong? If so, cool! Would love to have something more standardised than just a 1:1 mapping from rethinkdb or thinky calls over websockets/socket.io.
[1] https://github.com/facebook/graphql/blob/master/rfcs/Subscri...
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 :/
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.Json API has standards for how to do related records.
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).
It has support for "related resources" and even "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.
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.
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_).
>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-hyperte...
http://graphql.org/learn/queries/#variables http://graphql.org/learn/pagination/
+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.
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.
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).
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
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.
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.
what are the downsides of rpc approach as compared to rest and graphql?