The Discourse API in GraphQL

(Sander Datema) #1

@sashko (Meteor developer) wrote a post om Medium about GraphQL, using Discourse as example.

(Erick Guan) #2

The article is decent as it shows the problem in the REST. I am wondering the next post in the series…

The problem comes to GraphQL may be that there is no robust backend solution for GraphQL. It’s nearly write SQL in GraphQL which made it hard to parse. GraphQL has been released almost a year and I didn’t hear famous backend solutions. But some startup are using GraphQL to power their React infrastructure.

While Discourse has several complicated endpoints to hide the details. It will be just so hard to write the backend…

(Robin Ward) #3

This is a very interesting article!

I was the one who wrote the first Discourse prototype that evolved into the code base it is today, so I have the advantage of remembering why I made most of those early decisions around the API.

At the time (4 years ago!) there simply weren’t any mature libraries to do this kind of thing from Javascript, or if they were they were not even close to my radar.

For performance reasons, the common advice at the time was to minimize requests by returning large object graphs that mapped to your views. One monolithic request was seen as better than several smaller requests. Performance is an advantage we definitely want, but there are obvious disadvantages to this as pointed out in the article.

You’ll notice it results in less specific mappings of resources. A TopicView is a resource we request to render a topic rather than simply a Topic. We do this so that we can include a bunch of extra stuff we know we’ll need to render the topic.

Having said all that, clearly the API approach has scaled well for us so far. Our app is performant and we’ve been able to re-use the REST API in quite a few surprising ways.

I am curious as to how a GraphQL implementation would look, both from a server and client side standpoint. My gut feeling is it would be quite a lot of code and it would not be realistic to replace our current REST APIs any time soon. On the other hand, Discourse has already evolved quite a bit (CoffeeScript -> ES5 -> ES6, Ajax calls -> Promises -> Store, Rails 3 -> 4, etc) and I am always up for slowly updating to new and better ways of doing things when they can be demonstrated.

I eagerly await more articles in the series to see the path it takes. Thanks to @sashko for the excellent write up.

(Sashko Stubailo) #4

So far, I’m focusing on writing it as a separate service layer on top of REST - so the backend API of Discourse remains identical to what it is today, but someone like a mobile app developer can choose to use the GraphQL API if they find it easier.

It’s important that you don’t have to write your backend in JavaScript - it would be crazy to do a complete rewrite at this point! But with the approach of an API wrapper, the developers that are using the REST API and are happy writing the backend in Rails and ActiveRecord can continue doing so.

Part of the project we are working on now is about making it very very easy to write a GraphQL wrapper around any HTTP API, so future posts will demonstrate how that applies to an API like Discourse. We’re also working on a simple yet robust GraphQL client so that it’s easy to build the backend and frontend parts of your app.

I’m excited that people see the potential here, even if there is some skepticism about the difficulty of the implementation—that’s exactly the part we want to improve :]

(Sander Datema) #5

Do you mean that Apollo could not only be used for Meteor, but for things like Discourse as well?

(Sashko Stubailo) #6

That’s exactly right! It’s a data middleware that lives between your backend APIs and your client, which will let you do a lot of great stuff to make app development easier. This article is part of a series on the way to a complete demo of an initial version of Apollo that I think will be very exciting for people, and we picked Discourse specifically because it’s built with technologies that have absolutely nothing in common with Meteor today.

(matt debergalis) #8

I think this is as true today as ever.

The problems are 1) it’s now much more common to have multiple clients with different features / data needs; and 2) people are excited about microservices, but it’s hard to break a backend into separate parts without losing these optimized APIs.

(Robin Ward) #9

With HTTP2 though, this is significantly less of a problem!

(matt debergalis) #10

Maaaaaybe. You still have O(lg n) roundtrips to a “normalized” REST API to
get a tree of data.

The other thing is GraphQL opens up a number of other valuable
optimizations. Projections on the server (clients don’t fetch fields they
don’t need) and fine-grained caching (clients don’t have to refetch data
they already have). These aren’t possible in any reasonably generic /
composable way over REST.

··· On Thu, Mar 17, 2016 at 11:36 AM, Robin Ward wrote:

eviltrout Robin Ward co-founder
March 17


I think this is as true today as ever.

With HTTP2 though, this is significantly less of a problem!

Reply to this email to respond

In Reply To
debergalis matt debergalis customer
March 17
I think this is as true today as ever. The problems are 1) it’s now much
more common to have multiple clients with different features / data needs;
and 2) people are excited about microservices, but it’s hard to break a
backend into separate parts without losing these optimized APIs.

Reply to this email to respond

(Sashko Stubailo) #11

I have heard that some people have APIs where they can use query parameters to specify both filtered fields, and nested data requests. But GraphQL is basically a standardized way to do the same thing, so at that point it seems like you may as well use GraphQL.

(Cortlandt Winters) #12

Thanks sashco, I’m really glad that you are looking into this. One of the reasons I’m focusing my time on looking at discourse is to investigate these kinds of issues as they reply to a well-engineered real world application and it’s great to see that other folk are doing the same.

I don’t know if there is anything practical here for the discourse team, but discourse is a great starting point to explore this.

I would like to mention breeze.js and jaydata as things to possibly look at as odata has been around for years and never seems to get mentioned with graphql, but covers the same use cases and is pretty mature. Graphql seems cleaner, but we are missing an opportunity to relate their approaches if we just forget about it or don’t know that it exists.

I thought breeze was interesting. It worked out of the box if you were using sql server and entity framework as it used the entity frameworks metadata (with a big caveat about version matching), but then they extracted that part out into a javascript library so that you could put the javascript library on the server and use it there to create your own metadata by script or by hand when using mongo or postgres.

This is a quick overview of the idea

I think that the biggest problems graphql will face are similar, crafting the schemas in particular, then authentication and authorization and finally the simple but necessary mapping of the different server side language conventions to javascript. If I’m right the graphql structure makes it so that cycles are not a problem, is that right?

Probably just for any trivia buffs in the end, but I thought it was at least worth mentioning. I’ll be following what you do here for sure.

(Sashko Stubailo) #13

Yep, I think this is spot on. But it’s important to separate GraphQL from JavaScript - there happen to be a lot of libraries that combine the two, but GraphQL by itself is independent of any specific implementation or transport, which is very important for people who aren’t interested in writing JavaScript at all (for example, native mobile app developers with a Rails backend).

I’m excited to learn more and I’ll share it as I do!