Hacker News new | past | comments | ask | show | jobs | submit login
GraphQL Working Draft (facebook.github.io)
204 points by samhoggnz on July 2, 2015 | hide | past | favorite | 69 comments



Lee Byron is talking about it at React Europe right now, here's the live stream (which supports play back): https://www.youtube.com/watch?v=UclvvqNtNNo



That link says "This video is private".


I believe the event ended so they marked the stream as private.


I always enjoyed XPath as a lighter-weight mechanism for querying trees. It turns out that there are a set of pretty straightforward changes that can be made to XPath to have it support graphs. To wit: add a notion of a named 'traverser' (depth- vs breadth- search; pre-, in-, or post- order; how nodes are marked; etc.); then, change the notion of 'parent' to 'in' and 'child' to 'out'. XPath can then be implemented as syntactic sugar on top of this lower level "Graph Path" mechanism.

I'd always intended to convince my advisor to have the grad students do a graph-path implementation on top of boost::graph, in his generic programming course; alas, never happened. The 'masters' version of this would be to do a lazily evaluated version of graph path in C++ and Haskell to "teach them the students a lesson".


Why not have the query in JSON? Now you need a new parser.

EDIT: Thanks for all the replies, all of them very good points, and clearly show that JSON is not the most elegant option for a complex DSL.


There are certain things that are a bit more elegant if you can have a custom query language. One example:

        query UseFragment {
          luke: human(id: "1000") {
            ...HumanFragment
          }
          leia: human(id: "1003") {
            ...HumanFragment
          }
        }
        fragment HumanFragment on Human {
          name
          homePlanet
        }
You could definitely have some JSON to represent this but it might turn out to be more trouble than it's worth...


What about YAML?


It's sad that you capitulated. I agree with your original point more. Is this thing really flexible, composable, and implementable? How long do we have to wait for people to provide solid implementations on top of all the popular programming language and database backends? Feels like SQL all over again. Someone will be writing layers on top of this in javascript in the frontend and ruby/python/javascript/etc. in the backend. Then we are in another ORM hell. (Perhaps I am being too pessimistic here, it could very well be great, but I have some serious reservations...)


the query contains by far more logic than should be put into json

you could map it to json - but technically you could map everything to json - doesnt mean you decrease complexity

the parser is the lowest problem of parsing and optimizing those queries i'd assume


Readability I guess. The new syntax looks pretty good to me. A little heavy on the (( and )) but very obvious as to what is being asked.


I wonder how important readability is in this case, though. How likely is it that this language will be written (or read) directly by people, rather than generated and consumed by programs? The potential bugs in generators and parsers (think SQL injection) seem like a real cost, which I would have thought would outweigh the benefit of improved readability.


GraphQL is definitely designed to be written by developers, not by tools. We have a feature called query variables that provides the same strong typing to input values for queries that need to fetch different data dynamically.


I'm guessing you might want some 'small' parts of logic, like the unary operation. Guessing!


MongoDB did JSON queries. After having useed it I don't think it's a good idea at all.


I believe Netflix's Falcor, which seems very similar to Relay, uses JSON.


Where in the world is Falcor? We keep hearing about it, we saw the presentation, but this is all we've got and it's nothing: https://github.com/michaelbpaulson/Falcor


I had made a comment on twitter that the ref: concept basically throws json off the indecidability cliff in terms of parsing. They opened an issue for it apparently, but you can see the graphql rfc has specific anti-cycle checks, which is super important.


Finally! It's exciting to see a serious challenger to the cult of REST.


> cult of REST

Is this a thing?


Yes, we have regular meetings where we worship a statue of Roy Fielding and debate the merits of HAL over JSON Hyper Schema. Long live HATEOAS!



:O


Got curious about how the spec is built. Source said:

> Built with spec-md

http://leebyron.com/spec-md/


So, I haven't had enough time to really dig into the spec but it doesn't seem like the language has any kind of insert or update type of feature. Perhaps I just missed it though.

But if it doesn't it seems like you would need a pretty large dataset to make this worth it, right? I mean for any kind of a change event you still need to support a standard REST API, as this really only replaces the GET operation. Am I missing something on it? I certainly not saying it's not a cool idea or base to build from, just want to make sure I'm not skipping over an important piece.


GraphQL doesn't prescribe a particular approach to mutations; it allows the server developer to specify what mutations are available. For example, at Facebook we have a storyCreate mutation, and a friendRequestAdd mutation.

Mutations are just top level fields, but with side effects; because they are fields, the client sends up a selection set with the mutation. This allows the client to receive whatever data it needs to refresh, as the response to the mutation.

GraphQL was originally designed for reads, but we added write support to solve the parallel problem we were having with writes: different clients wanted different data back from the server after they performed a write. GraphQL gave us that capability.


Awesome, thanks for the explanation. My team is rolling out an REST API currently and I've always wanted a Linq/SQL type of interface to REST API's. I could definitely see GraphQL evolving in that kind of direction. Some amazingly cool open source tech coming out of Facebook these days.


I'd suggest that you be wary of going down the route of making your API too flexible. It becomes very difficult to scale up a service that provides flexibility.

Imagine a simple case where you're storing hundreds of records of users, and providing the flexibility to order by any field on the user, and of course, you're paginating those results. Now, scale up; you're storing tens of millions of those same record... how do you quickly retrieve the first ten records ordered by their e-mail address field? Same thing, ordered by their last name. Same thing, ordered by their country. Did you just create database indexes to support each of those use cases? Ugh.

In my opinion, a REST API (well, any API) should be limited to supporting only the business use-cases it is designed to implement. I wouldn't want to build a "Linq/SQL" type of interface, because then I have to support all the weird queries people will come up, and still meet my requirements to scale over time. Don't provide this kind of flexibility unless the value it gives your product is absolutely incredible, because, the headaches it provides could be equally incredible.


> Imagine a simple case where you're storing hundreds of records of users, and providing the flexibility to order by any field on the user...

You don't have to allow ordering by any field. You can define a list of fields that you can order by, and only allow those. I don't see the problem with doing that. But if you must allow ordering by any field...

> Did you just create database indexes to support each of those use cases? Ugh.

...then yes, you would need to do that.

I think the cool thing about GraphQL (at least from my understanding) is it doesn't necessarily give you full power to query data in any arbitrary way from the client--it just provides a more flexible interface for defining what data you want returned from the API and how you want that data structured. It doesn't necessarily have to be a 1:1 mapping of your DB schema, and in most cases I don't think it should be.


This is a great sum-up of a point I often find myself making a lot when explaining GraphQL. GraphQL is only capable of doing exactly what the server-side developer lets it. Order-by is a really great example. We can sort by only the things that make sense to sort by, and often at Facebook we're sorting by heuristics like "sort my friends by how likely I am to send them a message" when loading the friends in a typeahead for chat, and this idea of "message send likelihood" is not exposed as a field.


Maybe OData?


GraphQL seems to go hand-in-hand with Relay, and there's a talk on mutations in Relay here:

https://speakerdeck.com/laneyk/mutations-in-relay

That might provide the answers you're looking for. It's worth reading all the notes as I think this is the best resource for understanding how React + Relay + GraphQL really works.

You basically use GraphQL with a payload (the data to mutate and the mutation type) to select what to change and what data is returned after the change.


Just fyi, the doc mentions mutations here: http://facebook.github.io/graphql/#sec-Language.Operations



With a talk from earlier this year that describes an implementation: https://facebook.github.io/react/blog/2015/02/20/introducing...


There was a comment on the original blog post that while they (Facebook) use GraphQL they still fall back to Flux for some of the data handling.

Was this solved ? Did they manage to handle all the data needs of their apps with GraphQL or is it still limited to certain areas ?


They are orthogonal; graph ql is for fetching data and is supposed to be an alternative to writing a new backend endpoint for every ui-thing that needs some slice of data, flux is a pattern for organizing data flow in the UI.


I think you mean falling back to "FQL," the old SQL-like syntax, since Flux is more of a client architecture thing (paired with GraphQL).

FQL has some holdouts in legacy code, but the vast majority of the iOS app is using GraphQL. There are a bunch of tools built around using it, and it's the "right way" these days. Maybe a year or more ago ago, the notifications tab was using FQL. It makes sense to convert things since the risk in switching is outweighed by a reduction in server CPU, network bytes transferred, and ability of tools to understand the code. When we built Paper, we did notifications on GraphQL because there wasn't the risk of breaking something.

You can almost certainly handle all of your 'data needs' with GraphQL... :D


I think the OP meant Flux. I also read about it being used to store things that are not being persisted.


Fair enough. In that case, yeah, GraphQL is about the server communication and doesn't specify a particular application architecture. There's usually some data you want saved locally and not persisted to the server, though that's not very common in facebook, since eg preferences are meant to work across devices.


I've been looking forward to this! One question; it appears as though the types and schema are passed with every request (eg https://github.com/graphql/graphql-js/blob/master/src/graphq... ) -- I assume part of the reason for this is versioning/sharing the schema, but is it always external, does the server ever know the schema a priori -- what's the thinking around this design decision?

(It's a plausible idea! I'm just curious on the what and why)


Perhaps that code is a bit misleading. The schema itself is defined and provided by the server. The idea being that a server would build up it's type definitions, and then call into graphql's executor providing both the schema the server defined (in code) as well as the query the client provided (as a network request)


It's passed to that function in the reference implementation, but a server would probably create a helper function that runs a query for a particular schema. For example, you can just pass a query to Facebook's GraphQL endpoint (without specifying a schema), and it will run the query on the Facebook schema.


This is also reasonable; but an example of how schema get created and discovered by a client would be a nice extension to the spec. :)


Would love to see a more robust server backend for this, but I am assuming it's still a long way off.

A standard is a very good start. I notice the license is BSD, but is this patent encumbered?


There's a JS server provided: https://github.com/graphql/graphql-js.


> It is not a fully standalone GraphQL server that a client developer could use to start manipulating and querying data.... The only “backend” we have targeted for this early preview are in-memory stubs in test cases.

> To that end the target audience is not the client developer, but those who have or are actively interested in building their own GraphQL implementations and tools.

I guess I'm kind of happy that FB are releasing something regarding GraphQL since introducing it in February. I just thought they got busy with React Native and forgot about everything else they hyped up back in February.


Unlike with RESTful APIs, a server basically only needs a single endpoint that parses and responds to GraphQL commands. This isn't as far off as you suppose to be the case.


The trickiness will come in handling authentication for all the nested resources (e.g., user X can only see public photos for user Y, and can't update them) and generating efficient queries to a relational datastore. Coming up with a clean architecture for that actually seems like a fun project!


Yes, this is exactly the hard/interesting part to implement. Facebook uses their own graph databases which lets you specify access control rules. You'd need something similar on top of SQL.


You mean handling authorization.


It's a good thing that relational databases solved the problem of generating efficient execution plans for ad-hoc queries about thirty years ago—with SQL.


Yeah, but the stupid users insist on clicking buttons and stuff instead of typing in SQL.


The point is that relational databases will serve as the data model for most GraphQL application servers. Obviously, end-users don't have to write their own queries.


Also, keep in mind that most big websites aren't just a single box you can query. A plan for fetching data across >>1000s of boxes works a bit differently than within MySQL or whatever.

Usually you end up making layers of abstraction / cacheing / parallelization atop them that don't have an easy SQL interface for the frontend to query. FQL was heavily sanitized and abstracted anyway, not directly SQL onto the boxes--imagine that security shitshow!


How does this fit in/differ from Netflix's Falcor? https://twitter.com/falcorjs


They are attempting to solve similar problems: describing data needs on a client in a way that integrates well with how the data is used, and fulfilling those requirements efficiently.

Falcor uses some different primitives to accomplish the task, focusing on connecting together Observables, whereas GraphQL queries are written in a small query language.

Falcor is a super interesting project and we've gotten to swap notes a couple times.


Awesome, thanks. I watched the Falcor presentation and had my mind blown; looking forward to a similar explanation of GraphQL.


Lol - the code example seems to imply that Zuckerburg's user id is 4.


That's because it is 4!

https://www.facebook.com/4


As a ruby programmer, my gut reaction was that this had something to do with bugs caused by the object id of `nil` being 4. But of course that's not the case :)


You need to upgrade your Ruby version. The object id of `nil` is 8 these days :)


Ha, well they also got rid of `id` on nil altogether, so it stopped being a common bug. (I didn't know that its object id is actually 8 now though, so thanks for the useless-knowledge-nugget.)


Who is 1,2,3 ?


You could always try...

  - https://www.facebook.com/1
  - https://www.facebook.com/2
  - https://www.facebook.com/3
My guess (and there may even be apocrypha about it), is that these were old registration test accounts that didn't survive the first Zuckerbergian purge.


Correct. SQL auto increment keys plus test accounts resulted in Zuck being 4.


It is :)


Are there any plans to release the Relay (client side) component of this?


Joe Savona says August.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: