Hacker News new | past | comments | ask | show | jobs | submit login
How to GraphQL – A Fullstack Tutorial for GraphQL (howtographql.com)
298 points by sorenbs on July 11, 2017 | hide | past | web | favorite | 79 comments

Hey everyone

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

I like USING GraphQL (for existing services), like Github's API.

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.

This is a problem. It’s shocking people blow off not including that part. The current ORM’s out there kind of suck. I have been building a production app for a couple months now and that has been the biggest annoyance.

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

The problem with using a relational database with GraphQL seems like you need to solve the object relational mismatch. I think in that case you'd be better off writing a library for parsing SQL then putting a secure layer over it that limits what SQL is allowed.

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.

What about using GraphQL implies that you're trying to map objects from the database? As far as I know you can just query for the fields you want (with whatever joins you might need, or subqueries, or calls out to some other system) and return them to the client.

It's doing object mapping because it is coercing everything into JSON. Looking at the language, you see the usual suspects of strange cyclic objects for representing relations typical of ORMs. These systems tend to struggle when dealing with things like many to many relationships, non-total relations, etc. To give it credit though, I do like that GraphQL forces a firm separation between remote and local data, though I'm sure there are already libraries for GraphQL trampling over that separation.

there is, PostgreSQL https://blog.2ndquadrant.com/application-users-vs-row-level-...

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

Thanks for the info!

Just wanted to give a huge shout-out to PostgREST:



You can get many of the benefits of GraphQL using postgrest's 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.

IMO modeling your api directly off of your database tables is often an anti-pattern. One of the biggest mistakes I see people make is assuming their api's data model has to match their database's. It's common to introduce resources on the api side that may not have their own table in the database. For example, you could have a table that has a "type" flag (to model some kind of inheritance), but on the api you expose these as separate resources. Or you could have a larger resource on the api, but it's actually backed by several tables.

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.

If you treat PostgREST as an ORM, then you can easily decouple the database data model from the API representation. I imagine there are scenarios in which PostgREST would outperform certain ORMs implemented in dynamically-typed languages.

This is exactly my usecase. I replaced my NodeJs ORM layer with PostgREST and express apis layer with Aws ApiGateway.

Have you heard of views and FDW?

Views are only a solution for reads, not writes. FDWs are not an elegant solution to anything related to this. Think microservices that already have an api defined.

Many views are "auto updatable" in Postgres, meaning the db knows how to seamlessly pass updates down to the underlying relation. https://www.postgresql.org/docs/current/static/rules-views.h...

For more updates to more complicated views (such as some joins), you can use a trigger as also described in the linked docs above.

Your original comment said it's bad to couple your api with tables so I am agreeing with you, use views to decouple. for writes, you can use stored procedures for corner cases although most of the apps work with one model at a time, so auto-updatable views work most of the time. So if we take into account that most apps talk to one database, i have most of it covered with simple views since usually you have a 80/20 read/write split? I'll take that.

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

Also doesn't PostgREST handle PostgreSQL custom upgradable view?

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)

I looked at PosgREST for a backend for my Startup. Documentation was confusing, I couldn't see a coherent way to use it securely and the examples of other sites on Github were confusing. GraphQL at this time seems higher quality and also would be a good feature for PostgREST.

Fair point about the docs, I've been putting reference information in them over time, but it could use more guided tutorials.

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.

working on a coherent way here https://github.com/subzerocloud/postgrest-starter-kit/wiki

writing docs is hard but what do you expect :), GraphQL is FB funded, PostgREST is 3-4 guys, no backing.

Why can't you expose it to your users and why is PostgreSQL bases authorization not good enough?

where are you using it? (and you can even get GraphQL on top of it :P https://subzero.cloud)

when you say proxy do you mean literally nginx/something or some go/java/etc. http server?

i don't understand how one would use this? obviously you're not just exposing this api to users right? are you just using it as a substitute for an orm or data access layer in your own app?

As I see it PostgREST might finally be a way for backend database developer to easily provide and manage external web API that can then be used by all magical multi-headed unicorn powered and sparkling star enabled web framework of next month.

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

I bet they ar doing exactly that, exposing the api supported by PostgREST :)


Edit: seems they are not, ... oh well :)

business logic in sql seems like a bad idea (especially since you can't connect it to other services? or can you make ajax requests in sql?).

Business logic in SQL is a bad idea because it's much easier (for most people, anyway) to write and test it in a normal programming language. Especially if you want to have nice things like logging, breakpoints / inspection, composition / reuse, nice exception handling, etc..

developer tooling is indeed not on the same level as other languages but don't say it does not exist https://www.pgadmin.org/docs/pgadmin3/1.22/debugger.html

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.

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

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.

PostgreSQL vs Sqlie - sure, no argument there, i am talking about a reasonably complex thing like PG/Oracle/MsSql.

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.

til there's a debugger in pgadmin3. will very much come in handy i'm sure. thanks.

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.

And why do you say that you don't have composition/reuse when you very well can use JS/Perl/Python to write your stored procedures (or even C and load it as a extension).

Well, you can write stored procedures in JS/Perl/Python for Postgres, but not necessarily for other databases. And if you do it's probably not portable. And the fact that this capability exists I think is some evidence that sometimes you can't do enough with SQL to do everything you need in SQL.

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.

python for stored procedures: bring code to the data, not data to the code, i.e. it's much much faster because there is no overhead for shuffling data over the network, a few serializing steps and everything in between.

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/

you can if you really want to, but you are not supposed to. this tool gives you a way to talk to your database, not other systems. to talk to 3rd party systems you use other components in the stack (openresty/rabbitmq) https://github.com/subzerocloud/postgrest-starter-kit

Why use GraphQL? Why not simply expose one endpoint that takes a sql data parameter, queries the db and return the result set as json?

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.

What happens when your backend isn't SQL? Then you'll need to accept a different query language as well. Wait - maybe those could be abstracted into a single query language? Ah, it's GraphQL!

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.

Regarding the last point, yes, that's what I'm saying. And it's not a matter of opinion, but of decades of computer engineering best practices.

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?

I recently started using GraphQL and I love.

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.

I've looked a bit through the GraohQL syntax. While it is an immense improvement over plain Rest, I dislike the abuse of JSON as a query language. I think it would be better if it were a true DSL like SQL or some sort of Lisp.

Instead of allPersons, I think it would be cleaner and easier to understand as

(all Person)

Which makes the generic nature of "all" explicit.

The thing is that the "all" is actually _not_ generic in this case. The GraphQL server implementor has to specify a field called that specifically.

What I've not understood about GraphQL is how to map it to My/Postgre/etc SQL. The info about resolving specific fields seems .. complex, and difficult to optimize tom say, reduce SQL calls.

Is there a library that, say for Golang, helps translate a GraphQL Query into SQL statements to actually get the data?

I'm interested in learning solutions for this as well, but it's hard to find because most GraphQL tutorials stop at the resolver level.

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!

Hey! I'm one of the co-authors of the Elixir implementation Absinthe. Absinthe has an extensible middleware mechanism from which you can build a variety of different batching patterns.

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?

In a side project of mine, I leverage https://github.com/neelance/graphql-go, which is one such implementation written in Go.

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.

You might be interested in postgraphql: https://github.com/postgraphql/postgraphql

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.

Anyone aware of a MySQL equivalent?

If it helps there's official SQLAlchemy support from Graphene, so you could use that with MySQL (provided you like using Python). If you use DataLoader with it then you should be pretty database agnostic.

I've read comments here on HN that the server side of graphQL is notorious hard to implement, the resolvers end up being really complicated or slow.

Anyone care to comment from practical experience?

I've implemented three graphql backends - one wrapping a rest api, one wrapping mongo, and one wrapping postgres. The key, just like in rest, is to keep the different layers isolated. If your resolvers never do anything more complicated than parsing arguments and passing them to the next layer, it's hard to make them complicated. One project parses the graphql ast and there's a small performance gain from that, and another batches identical requests with Facebook's DataLoader library, but those are done behind the scenes and don't end up polluting the resolvers, and to be honest they probably weren't necessary.

Most of the resolvers end up looking something like

    type: FooType, 
    args: {
      fooId: GraphQLString,
    resolver: createRESTResolver(
      ({ fooId }) => [`${services.foo}/:fooId`, { fooId }] 
but if I was doing it again I'd probably abstract the creation of the entire field rather than just the resolver.

2 years of experience, it's easy. As long as you resist the temptation to build clever abstractions too soon, there's nothing hard about it.

https://subzero.cloud (1 query, optimal for any number of levels)

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 )

I haven't played with the Golang server yet, but with Node you just set the resolve to something like:

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

It's fantastic to see a tutorial that separates the frontend from the backend. As someone that _doesn't_ work in web technologies, it can be tough to follow basic tutorials or take them to the next level when you're trying to understand node, npm and webpack, as well as the concept you want to learn: GraphQL, which although hyped, does look like it brings substantial value to the table.

If you are a starter don't worry about it at this point. A good REST API and understanding of how that works is a really good foundation for web development that you can take with you from language to language and project to project. This is a cool but still relatively niche technology.

My interest in GraphQL has a few different layers: it's a different querying paradigm, in the same way that REST and RPC paradigms are different; what are the pros and cons? How do you optimise services throughout your stack to handle load that is - in theory - of an unknown pattern, but in practice, will be of certain shapes? Furthermore, if we divide SOA/microservices into several tiers - separating UI services from backend services - does GraphQL fair better than more traditional paradigms? How do we "merge" GraphQL schemas?

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.

I've only given a cursory look into it, and with regards to building a JSON API in Rails (of which the many extant standards and their Rails libraries are still immature), is this just another fad, or an actual API standard that has staying power? It seems like the latter, but given that it's Facebook-backed, as soon as they get tired of it, they could pull a Google on it.

There is a practical, functional GraphQL spec that has multiple client and server implementations. Regardless of whether Facebook continues to develop clients or maintains stewardship of the spec, GraphQL has a lengthy future ahead.

I have personally found it to be a practical, useful API standard that provides benefits over a JSON API in Rails. I wrote an article about some of the benefits a couple of years ago: https://0x2a.sh/from-rest-to-graphql-b4e95e94c26b.

You can architect "traditional" Rails APIs to get some of the similar benefits, but GraphQL works out of the box with existing client libraries.

We've been using GraphQL at Facebook in production for almost five years now, and it powers a huge amount of our iOS/Android app's API traffic. We also did a comprehensive revisit of the core concepts when we open sourced it in 2015, and we heavily use tools like GraphiQL internally. I can definitely assure you that Facebook's support/usage of GraphQL isn't a fad.

I have recently started learning React and I am following the lessons in www.hotwographql.com. I am trying to decide which GraphQL library to use for the practical exercise. Should I go for Relay or Apollo?

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.

How to choose between Relay & Apollo is one of the most common questions people ask when they get started with GraphQL! In general, it definitely depends on your project and what you're optimizing for.

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

I've found that Apollo stack is more user friendly for learning. I didn't try in a production environment, but unless there's a huge difference in performance I'd use Apollo.

GraphQl really seems to be a step up from REST. The complexity of the client/server-libraries will increase but that's ok.

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.

Awesome resource! I've been playing around with GraphQL on a Node/React+Apollo project and found it very useful and fun to use.

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?

I can't speak to the entirity of your question, but the last part I will address: "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.

Thanks a lot this was exactly what I was looking for :) sorry if the question was a bit fuzzy.

I just read more and played with GraphQL just the other day, and it's really an amazing and powerful tool.

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.

I am curious to here about any experiences implementing a GraphQL backend in production on .NET (non-Core) + SQL Server. Even React feels left out here in my neck of the woods.

Great job. Awesome to see all the focus on documentation and conceptual explanations. Clear messaging and spreading understanding are just as important as the tech.

Awesome! I'll share it with GraphQL Stockholm.

Is GraphQL substantially better than OData (created 5 years earlier)?

Exactly what I was looking for. Thanks team behind this.

Nice job! Great source for learning Graphql :)

Heyhey! I heard a lot about GraphQL before, but I'm not quite sure what it is. Is it similar to Neo4j?

Hey! That's actually a pretty common misconception people have about GraphQL when they first hear about it - however, GraphQL definitely is not a Graph database (as is Neo4j). In fact, it's not even a database technology, despite sharing the same suffix with SQL!

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

Some of the introductory material in the resource will fill you in on what GraphQL is.

The GraphQL has a diversity problem. :)

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