How to GraphQL – A Fullstack Tutorial for GraphQL
howtographql.com
howtographql.com
We're super excited to finally launch this resource that we've worked on together with amazing members of the GraphQL community! The goal of How to GraphQL is to provide an entry-point for all developers to get started with GraphQL - no matter what their background is.
The whole site is open-source and completely free to use! If you want to contribute a tutorial because your favorite language is still missing, please get in touch with us!
Here's the official announcement blog post on the Graphcool blog: https://www.graph.cool/blog/2017-07-11-howtographql-xaixed1a...
If you find a bug or another problem, create an issue or submit a PR on the GitHub repo: https://github.com/howtographql/howtographql
Follow us on Twitter to be informed about new content that's added to the site: https://twitter.com/graphcool
However, 99% of the tutorials on graphql , this one included, fail to show a real life use case. What I mean by that is a working Example of a SQL database from start to finish.
So this tutorial was very cool, but not very useful. Just like the rest of them.
I've yet to find a recent tutorial that covers full stack node.js + PostgreSQL/MySQL + whatever front end. It's always MongoDB or only covers the concepts of GraphQL.
Ideally, you'd be able to just handle these security issues with the database directly through views and permissions, but as far as I know there is no database with enough permissions controls for this.
(and saying GraphQL can't work with databases I think is wrong, it's the same as saying OO languages are not a good fit for relational databases)
I have gotten by using eager loaded relationships and facebook’s dataloader to prevent n+1 query problems. Overall, I have found minimal extra queries.
At the same time, I wish I could devote time to make an orm that works like facebook’s dataloader. It would be so awesome. In fact I might try to do something like it myself. Inside of the user resolver on a post, just return Model.eager(“user”) and have it wait to resolve on the next tick. This would get us to a perfect world with node and graphql!!
https://github.com/begriffs/postgrest
You can get many of the benefits of GraphQL using postgrest's resource embedding:
https://postgrest.com/en/v4.1/api.html#resource-embedding
We're using it in production.
PS: To be clear, you can't expose it directly to your users. We wrap it in a proxy service that provides authentication and authorization, and parses and transforms the users' URL queries destined for PostgREST. We also apply some transformations to the data coming back from PostgREST, such as encoding our internal UUIDs. It may sound complicated, but it's actually only about 200 lines of Erlang.
https://github.com/subzerocloud/postgrest-starter-kit/wiki/P...
Edit: seems they are not, ... oh well :)
logic that directly relates to the data being stored is much easier to express in the database (constraints), resulting in a big reduction of code which means small simple functions that almost don't need debugging.
also what people call business logic often means fetching data from the db, processing it in some way and returning it. This is what views are for, they are definitions, so there's nothing to test there, except performance maybe.
I think this is true for SQL experts (provided you're on the right database platform, of course - Postgres probably, MySQL and SQLite I doubt it) but it's not true for people with expertise in other language(s), which is the majority of people using the database. I can write arbitrarily complex business logic in Python and Javascript, which I am very familiar with. I would struggle to do that with SQL, and I know that all of my colleagues would struggle to understand what I had done. And I'm not unfamiliar with RDBMS - I've been working with them for years. Maybe that's a reflection on me, but I'd say it's been true of 95% of people I've ever worked with.
Well, of course, it's easy to use what you already know as opposed to the thing you don't, and i agree that most of the people don't know the capabilities of the databases but your comment implied that it's a bad idea in general and i can't agree with that.
The places where you would use SQL would be for reading data and some of them (views/queries) might get big, a bit complex but i doubt the equivalent code in any other language doing the same thing would be any simpler/easier to understand. I would bet the view code would be an order of magnitude shorter than the expression of the same problem in any other language, also you can use stored procedures (in any supported language) for reading.
For writing ... you don't have to use Pl/pgSql ... use your beloved Python/Perl/JavaScript :) the only difference the code is running in your database.
but i don't agree with this
>also what people call business logic often means fetching data from the db, processing it in some way and returning it. This is what views are for, they are definitions, so there's nothing to test there, except performance maybe.
i see business logic as things that connect disparate parts of the domain. not all of my business is in my db. a lot of it is somewhere else, in someone else's db, accessible only through their api. like i said in my op: unless you want to hack postgres (or whatever rdbms) into a full-fledged general use dev environment you're not going to be able to marshal all of these disparate resources.
Anyway, I was talking in generalities, not about Postgres specifically. I would argue that if you're going to use Python to write stored procedures, why not just write a traditional Python script/app with SQLAlchemy? That SQLAlchemy has an ORM capability doesn't mean it needs to be used that way, as it's creator takes pains to point out. And this is a much more common pattern for using Python with a database, which is to my original point that its easier for most people to do.
It's much more probable that you will switch your language/framework then changing the database. This fear of "database lock-in" is unreasonable and the source of many not so good patterns ( as in ORM :) ). The only reasonable rationale for fear of lock-in is Oracle :) but you again, it's unreasonable, and you even semi-automated processes for migrating https://aws.amazon.com/dms/
Errr... sorry... I ranted...
Another point of view would be that it could help frontend developer hook to a well defined API and never again have to dive into the seven hell madness of the underlying database ruled by a crazy monk that call himself dbadmin and draw mysterious SQL optimisation spell on the walls while yelling ACCCCIIIIDDDD! in the darkest hour of the night.
Humm... Damn... I guess I will be downvoted... Sorry --'
writing docs is hard but what do you expect :), GraphQL is FB funded, PostgREST is 3-4 guys, no backing.
Last week I began working to improve that, by writing a series of tutorials. Here's the first: https://postgrest.com/en/v4.1/tutorials/tut0.html
More to come, including tutorials about row-level security and authentication.
Graphql is also more generic and allows you to fetch from multiple data sources. These could be databases, apis, or wherever. You write code that fulfills each column and graphql assembles a single object.
I could see postgrest being ok for prototyping or simple apis, but it seems like one of those things that you'd grow out of eventually.
FDW are very elegant for reading data from other systems. If you can read from twitter https://github.com/umitanuki/twitter_fdw you can read from anything although I don't understand why you brought up microservices, this is one one of the microservices (that is talking to the db), it's not the thing trying to unite all microservices. You can have GraphQL on top of PostgREST just fine (https://subzero.cloud).
For instance, I already use this feature to present jsonb attributes as columns and edit them with a tool that is unaware of jsonb (QGIS). (NB: But not in a PostgREST context, using native connection)
For more updates to more complicated views (such as some joins), you can use a trigger as also described in the linked docs above.
Yes, you'd have to setup db security to allow those db commands to run only selects and restrict which tables are allowed to be queried.
How can using a new json query language, without any server libraries targetting relational databases be better than that?
How much work would be envolved to implement this on the server side and for what, exactly? to allow frontend devs to query without exposing separate endpoints?
Client-server applications should not run business code on the client. The only code that should run on the client is the UI's.
Sorry, this is simply wrong.
To your other points:
* no matter what you do to expose an API you have to set up security
* there are already server side solutions that help enormously with implementing your own endpoint
* I don't see the logic behind your client-server opinion. You seem to say that the server should be defining the data that the client needs.
Your app's UX will depend on how much code runs on the client. It can vary from a dumb terminal, like classic web applications, where everything runs on the server, to smart or rich clients, where some code do run on the client, but is always related to the UI. In a client-server application, your app's logic should always run on the server.
I've worked on desktop client-server apps where the application logic was on the client and the server was mainly the database. It works, but you might end with clients with different versions trying to access the DB and you don't want that.
That's what server validation means. You should never trust clients. You shouldn't build a web app, which is a client-server app, entirely on the client. It's like reverse best practices. It will bite you.
Regarding having something else than sql, how much effort would be necessary to build a graphql server library that abstracts whatever you have on the server? Would you build something and release it to your clients with that level of maturity? And for what?
The best thing about GraphQL is having a standard interface for queries (and more) and all tools that built upon it (such as Apollo). To name a few existing and upcoming (?) features from Apollo: Query batching, real-time updates (WebSockets + subscriptions), caching, optimistic UI, polling, pagination, live queries and many more.
Also, GraphiQL is pretty cool, too, basically Swagger for free.
Instead of allPersons, I think it would be cleaner and easier to understand as
(all Person)
Which makes the generic nature of "all" explicit.
Is there a library that, say for Golang, helps translate a GraphQL Query into SQL statements to actually get the data?
resolve (root, args) { return Db.models.post.findAll({ where: args }); }
(sorry for the lack of markup, I don't know how to do anything here yet)
Here's a blog post specifically for Golang: http://alexandrutopliceanu.ro/post/graphql-with-go-and-postg...
https://github.com/stems/join-monster (1 query, overhead for more than 2 levels)
https://github.com/facebook/dataloader (best case, 1 query per level, in sequence )
Otherwise it depends on your GraphQL implementation and what DB adapters or ORMs they support. For example, `graphql-ruby` includes a generator for a Rails-compatible GraphQL schema.
It might appear verbose at first, with it needing exported method names all over the place, but I've grown accustomed to it now. The repo has a full star wars example which helped me to get oriented quickly.
There are a couple approaches I've seen for mapping to an SQL backend.
One is batching - You get the top level resources, then save their accosted record IDs until later so you can make fewer calls to get their associations. This still makes quite a few database calls, especially for deeper queries or many different type of objects.
Another approach is "whole tree up-front" where you take the AST of the graph you're trying to resolve, and convert that to one big SQL query that joins all the associated objects. This can be more performant in some situations as it only makes a single database query, but a drawback is that larger queries eat up a more bandwidth from your query since having many joins causes data duplication. Another drawback is that having a single query makes it so you can't cache each resolver individually like you might be able to do with a batching solution.
I don't have all my links handy but here's one you can check out: https://github.com/facebook/dataloader
If anyone has something to add please chime in! I'd love to hear how people are really using GraphQL with SQL backends!
We run our API at http://www.cargosense.com/ entirely via GraphQL over quite a lot of postgres tables and this has remained very performant for us. Elixir makes it easy to do concurrent batched requests, as well as in memory caches that live for either the duration of the request or long as desired.
For some particularly complicated cases we have a materialized view, but this is largely used to power a reporting service that builds snapshots from this.
Any questions you have in particular?
Anyone care to comment from practical experience?
Most of the resolvers end up looking something like
{
type: FooType,
args: {
fooId: GraphQLString,
...paginate.args,
},
resolver: createRESTResolver(
({ fooId }) => [`${services.foo}/:fooId`, { fooId }]
).use(paginate),
}
but if I was doing it again I'd probably abstract the creation of the entire field rather than just the resolver.Whilst I agree it's niche now, not many new paradigms come along and not many of them have so many questions that can be asked, so there has to be something interesting there.
You can architect "traditional" Rails APIs to get some of the similar benefits, but GraphQL works out of the box with existing client libraries.
Also, I have been working as an Android developer for the last couple of years, and I was wondering how similar are the React and Android implementations of Apollo.
Relay is very mature and heavily optimized for performance, however, it's not very easy to understand and comes with a notable learning curve.
Apollo on the other hand is a community-driven effort to build a very flexible GraphQL client that still offers a powerful and intuitive API.
I'd actually suggest you try to go through both tutorials on How to GraphQL and see which one feels better for you :)
PS. In case you weren't aware of it - the second GraphQL Radio episode had Lee Byron and Joe Savona (both from Facebook/Relay) as well as Sashko Stubailo and Jonas Helfer (both from Apollo) as guests: www.graphqlradio.com
If I look at graphql-java I see:
- "The Java implementation of DataLoader is unfortunately still in the making."
- "While graphql-java does parse subscription requests, its support at the moment unfortunately stops there"
Seems it's not ready yet.
My background with backend is mostly PHP. Any good plans on adding PHP guide to backend section or is there no good GraphQL-server/implementation for PHP?
There are 2 good PHP servers: https://github.com/Youshido/GraphQL https://github.com/webonyx/graphql-php
It seems like the majority of the graphql-php community has rallied around the Webonyx implementation, including myself for my WPGraphQL project, a free open source WordPress plugin that brings a GraphQL API to WordPress (https://wpgraphql.com)
As the maintainer of WPGraphQL, I'd be interested in adding a section to the HowToGraphQL resource specific to using GraphQL with WordPress, but haven't had any official discussions with the maintainers of the project yet.
There are also implementations for Laravel and other projects, using that library.
Save requests and bandwidth, no need for explicit version control, and to top it off an easy to use syntax? Sign me up!
I'll definitely be using this in future projects.
GraphQL is a query language for APIs - so, the closest you could get is to say that GraphQL is an API technology! It defines a specific request/response-format for client-server communication that's extremely flexible, simple and efficient. GraphQL is also independent of the transport protocol that's used (though mostly that's HTTP today).
If you have a good idea about what an API is, you can read the second chapter of "How to GraphQL" where we highlight technical differences between GraphQL & REST: https://www.howtographql.com/basics/1-graphql-is-the-better-...