I don't think necessarily GraphQL is hard to understand as a concept. It's just difficult to figure out how to use it in an actual app context. How do I handle more complicated things such as authentication and, more importantly, what are acceptable and secure ways to structure your queries for auth (and things like that). I can certainly hack around with `context`, I just don't know what is actually good or not.
> I don't think necessarily GraphQL is hard to understand as a concept
It was surprising to us as well! But working with lots of users who are new to GraphQL, there are a few speed bumps along the way before you get to "implementing GraphQL in production." You have to convince your GraphQL users that:
1. It won't take too long to understand
2. It will be worth the effort
Anything you can do to make building a valid GraphQL query (both syntactically and semantically) faster helps with #1, and will get your users further along.
Making it so that users can see success/data flowing in as quickly as possible helps with #2.
From there, like you mentioned, there are lots of additional challenges, but for this post we're focusing on getting new users over the most initial hurdles.
I don't know what the stack you're working with looks like, but authentication can be done the same way as a REST API would - wherever you have your top-level handler that receives the HTTP request can accept/reject the request if it is invalid. So for example, you'd use the same express middleware you would normally if that was your stack. Its a bit simpler to wrap your head around from that perspective if you just think of it as any other POST request.
Authorization, that is, allowing users access to some things but not others, is more complicated and of course bespoke to your application. The simple solution is to simply check context in individual resolvers, which ends up looking a lot like a normal Express/Flask/Sinatra app.
There is a graphql-middleware package that helps structure "middleware" resolvers, and a graphql-shield package that helps with more complicated role-based logic.
This is really cool! I think that for the demo you should make the "Explorer" open by default - I bet most people won't realize what to do otherwise and will be intimidated (and just leave).
If possible it would be good to add default values too (like the "ticker" in the stock data set)!
Good idea! Just pushed up a change to open the explorer by default and fill in a default value for the stock ticker.
The explorer supports adding args that should be auto-checked and providing default values. It could probably be a little easier to use, but it's easy enough to add new ones once you have an example: https://github.com/OneGraph/graphiql-explorer-example/blob/m...
I’m a big fan of graphql and use it for all frontend work.
I ran into one issue recently from a server side client use case where I needed to quickly consume an entire endpoint. Since you need to define each field in your query, it was more time consuming to create the requests. I also see the issue if fields are added, you would miss that data without updating your query.
Typically these are benefits when doing frontend work, to limit data, but I did find it annoying when just needing to quickly dump data.
For my own servers moving forward, I’m going to be adding a _doc json field for users that need traditional rest endpoint functionality in a query.
If you don't want to specify all properties, or can't know them ahead of time, you can create a JSON scalar type that will return an arbitrary object (https://github.com/taion/graphql-type-json).
Its of course much better to define your attributes ahead-of-time. It incurs more overhead initially but pays off immensely down the line.
There are obviously tradeoffs that come with selecting all fields by default (in particular it makes it difficult for the server devs to send thoughtful notifications only to clients who rely on specific fields when necessary), but for initially exploring it's definitely nice.
Naive question: Is GraphQL meant to be used only by the frontend developers to consume backend data, etc? And not by the actual consumers of the API (ie customers, users)? If not, I don't see why consumers would ever want to use GraphQL.
Figuring out the syntax/language to do something as simple as retrieving the first X items requires more thought than calling a dead-simple REST endpoint.
Calling an endpoint is only half the story. You still need to know the shape of the response. And most rest APIs I've had to use do a suboptimal job at communicating the schema of the response.
Even Stripe's API, which is far ahead of most other APIs in terms of documentation, doesn't tell you basic things like whether a field can ever be null.
GraphQL defines an interface for describing the schema of an endpoint. This to me is the most valuable thing about it.
This is a great point - Stripe is one of the exceptional companies that maintains a great openapi spec though!
Even so, the GraphQL experience (with the explorer and some other OSS releases we have for next week) is still just so exciting https://serve.onegraph.com/short/Q8SE4F :D
query search {
stripe {
invoices(first: 10) {
nodes {
amountDue
nextPaymentAttempt
object
total
customer {
... on StripeCustomer {
id
email
}
}
charge {
dispute {
created
reason
status
}
}
}
}
}
}
- Type (and nullability!) of fields
- In-situ documentation on what the fields are for
- Ability to navigate the Stripe graph from any starting point (customer -> charges -> cards) in a single super-efficient call
- Search-ability across the whole Stripe API in a single field
- Potentially joins across services, e.g. from Stripe to Zendesk or Salesforce
I think GraphQL is absolutely suitable for being exposed as a public API. Given a schema, it's arguably simpler to write clients than with REST, where every API is completely ad-hoc with respect to how you pass parameters, paginate, select which fields (including nested data) you want, etc.
I think the more interesting question is whether GraphQL is a suitable inter-application API foundation. In many ways it aligns better with application requirements than gRPC. gRPC is even farther away from REST, with limited abilities to do field selection and no inherent support for nesting. And gRPC needs special help to work in browsers. What gRPC has is a compact serialization format and a toolchain that encourages using Protobuf structs for your own internals.
When implementing an app, it certainly seems redundant to offer both GraphQL and gRPC.
"standard": random endpoints returning JSON can be easy to use, once you're familiar with them, but you have to learn each endpoint separately. Hopefully GraphQL (or something like JSONAPI) will bring us a real standard interface to apis.
There's also openapi [1], but there's a real social/process challenge in keeping it in sync with the actual implementation. The tools that build on it are great, but there's a lot of surface area to cover when bolting on computer-understanding to an existing api.
GraphQL's approach of mandating introspection means more work in some areas, and far less in others. Searching for the data available in a REST api can be a big issue, for example, depending on the state of the documentation.
> more thought than calling a dead-simple REST endpoint
REST shortcomings aren't necessarily found in a single api request. REST's shortcomings are the handful of endpoints required to get the information you actually want.
> REST's shortcomings are the handful of endpoints required to get the information you actually want.
That's a problem of a naive CRUD API against a normalized relational datastore (or one structurally resembling such a store) regardless of architectural style, but there is no reason any standardized packet of information for which there is an expected recurring need should not be conceptualized as a resource in a REST API.
Orthogonality or normalization is not part of the REST architectural style.
This approach necessitates an ever growing number of increasingly specific APIs, or an ever growing set of flags and options which will inevitably approximate a poorly implemented version of GraphQL.
The biggest benefit for me is that since I'm working on both ends of the stack I don't constantly have to make little changes on the backend to accomplish what I want on the frontend. In the past I've ended up with an array of alternative endpoints using different methods or query parameters for special cases whereas now the particulars about what I want to retrieve is more delegated to what I'm doing on the frontend. It is also quicker in that I don't have to write client libraries as I go.
Even more, now I'm using postgrahile and don't even bother with writing the backend for much of anything except special case resolvers. This has increased my productive time but it might not be a fit for everyone. The nice thing is that I keep my schema in the app repo and have the entire thing provisioned from 1 script.
If I need a new resource I just modify the database schema and the graphql resolvers are created automatically.
> Figuring out the syntax/language to do something as simple as retrieving the first X items requires more thought than calling a dead-simple REST endpoint.
I'm obviously biased as one of the founders of OneGraph. There's a one-time cost of learning the syntax (which we're trying to make easier!), but once you've done that my experience is that it's easier to use a GraphQL endpoint from the backend than a REST endpoint.
We used Facebook's GraphQL endpoint from a Clojure backend when I joined the Wit team after they were acquired. It was very handy to be able to look at the query and have a general idea of the data that was going to be returned rather than inspect a response or look up the docs.
Also check out Hasura (https://hasura.io) which works on any Postgres anywhere. Hasura provides out-of-the-box GraphQL APIs which you can extend as well while hooking into any (web-based) external Auth system for role based access control.
We haven't made any custom GraphiQL for the desktop yet, I think we'll reach out to e.g. https://altair.sirmuel.design to see if we can get it to ship with OneGraph "preconfigured" with all of the open-source additions we're adding right now.