Settings

Theme

GraphQL Working Draft

facebook.github.io

204 points by samhoggnz 11 years ago · 70 comments

Reader

vjeux 11 years ago

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

thechao 11 years ago

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".

binarymax 11 years ago

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.

  • colinramsay 11 years ago

    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...
  • gniquil 11 years ago

    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...)

  • andreasklinger 11 years ago

    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

  • monk_e_boy 11 years ago

    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.

    • voyou 11 years ago

      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.

      • leebyron 11 years ago

        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.

  • seivan 11 years ago

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

  • dandellion 11 years ago

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

  • jackmoore 11 years ago

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

    • kolev 11 years ago

      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

      • nutate 11 years ago

        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.

applecore 11 years ago

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

smizell 11 years ago

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

> Built with spec-md

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

jaegerpicker 11 years ago

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.

  • dschafer 11 years ago

    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.

    • jaegerpicker 11 years ago

      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.

      • mfenniak 11 years ago

        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.

        • RussianCow 11 years ago

          > 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.

          • leebyron 11 years ago

            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.

      • br1 11 years ago

        Maybe OData?

  • colinramsay 11 years ago

    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.

  • jessep 11 years ago

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

hartror 11 years ago

Some background: https://facebook.github.io/react/blog/2015/05/01/graphql-int...

Murkin 11 years ago

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 ?

  • HeyImAlex 11 years ago

    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.

  • darknoon 11 years ago

    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

    • woah 11 years ago

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

      • darknoon 11 years ago

        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.

barakm 11 years ago

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)

  • leebyron 11 years ago

    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)

  • dschafer 11 years ago

    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.

    • barakm 11 years ago

      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. :)

cetra3 11 years ago

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?

  • spicyj 11 years ago

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

    • xtrumanx 11 years ago

      > 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.

  • applecore 11 years ago

    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.

    • stevepike 11 years ago

      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!

      • dgreensp 11 years ago

        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.

      • applecore 11 years ago

        You mean handling authorization.

      • applecore 11 years ago

        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.

        • TheCoelacanth 11 years ago

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

          • applecore 11 years ago

            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.

        • darknoon 11 years ago

          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!

porker 11 years ago

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

  • leebyron 11 years ago

    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.

    • porker 11 years ago

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

sinwave 11 years ago

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

  • samhoggnzOP 11 years ago

    That's because it is 4!

    https://www.facebook.com/4

  • sanderjd 11 years ago

    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 :)

    • judofyr 11 years ago

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

      • sanderjd 11 years ago

        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.)

  • revskill 11 years ago

    Who is 1,2,3 ?

    • ci5er 11 years ago

      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.
      • leebyron 11 years ago

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

  • prezjordan 11 years ago

    It is :)

tristanz 11 years ago

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

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection