Hacker News new | past | comments | ask | show | jobs | submit login

(disclaimer: I worked at Meteor/Apollo for about 5 years)

I love the callout to how this is continuing the vision for improving application development started with Meteor -- it really does feel that way to me. Apollo, supported by GraphQL is IMO really delivering on the vision of making a lot of aspects of client-rendered app development much more straightforward than they have been in the past.




Honest question, what about GraphQL is straight forward? As a web developer I've been curious about its hype for a long time but every time I look at its implementation I balk.

I have a lot of experience with JSON-REST APIs and RPC systems like gRPC and they both seem clearly superior (especially in tandem with code generators) where as GraphQL seems like a ton of extra work on the client and server side for little gain. When asked most developers say its because you can limit which fields you query, and I have to politely explain to them the existence of an SQL SELECT query...


On the front-end, with GraphQL you simply specify exactly the data you want on the client, e.g:

`GET localhost/graphql`, with body

dogs {

  name

  location {

    city

  }

  isAGoodBoy
}

...and I get back:

dogs: [

  {

    Fido,

    location: {

      Boston

    },

    true
  },
  {

    Spot,

    location: {

      Los Angeles

    },

    true

  },
  ...
]

No extra fields. My clients page doesn't care about the dog's UUID, weight, etc. No routes. Everything goes to `localhost/graphql`.

It makes writing clients an absolute joy, and it works gloriously with React. Tell the server exactly what you want, and get exactly that.

On the back-end, every field (name, isAGoodBoy) is a resolver. Maybe it's a simple database call to retrieve that field. Maybe it's some service that pulls crap from an S3 bucket. GraphQL doesn't care. So the level of difficulty of implementing a GQL server is dependent on your back-end. For most folks, you'll just be making calls to a database.


You can do the same with JSON:API Sparse field-sets. see documentation here https://jsonapi.org/format/#fetching-sparse-fieldsets. Hence what you've above is not really an advantage of only Graphql.


location in the example is a relationship with it's own fields though. We may want to get the top 5 items related to the locations we are fetching for example.

But I think the bigger difference is that we typically expect JSON:API urls to be generated while graphQL queries are more directly edited by the developer. I think that yields an experience that feels more direct.


> When asked most developers say its because you can limit which fields you query

For me this is one of the biggest headaches I have with a new app I've been assigned to. By allowing all fields to be optional depending on the graphql query, there's no consistency in the objects floating around in your apps data store. When I reference a Person object in my view that I'm using, will phone number be there or not, who knows.

Maybe its better when every single page has to request it's own data, but when the model objects are cached to a data store in an app and shared between views, things get really dicey.


A large part of GraphQL is the idea of tightly coupling queries to code, declaratively, combined with smart differential logic.

The original web framework for GraphQL was Facebook's Relay, which essentially lets you declare, in your component, what data you want. Relay stitches together your query and avoids work by figuring out the difference between what data the client has (in its cache) and hasn't.

Apollo's React framework is based around the same ideas. You're supposed to declare the query privately in the component that needs it, and in principle, caching should avoid many unnecessary fetches. For example, if you have:

  // In component A
  {
    currentUser { id, name }
    topStories { id, title }
  }

  // In component B
  {
    currentUser { name }
    favouriteTopics { id, name }
  }
then the delta from A to B is { favouriteTopics { id, name } }, and no re-fetching of currentUser is needed, since it is a subset that merely needs to be filtered.

(There are of course ways to write queries that will always conflict with each other, e.g. by applying different parameters such as filters to nested fields.)

In practice, I'm not sure if Apollo is that smart yet. I think it currently considers any difference in field selections to be a conflicting change, even strict subsets, but I could be wrong.

When used outside of React, GraphQL becomes more like SQL:

  for (const {name} of (await query(gql`{
    users { id, name }
  }`)).users {
    // ...
  }


Theoretically, a smart enough GraphQL front-end could recognize multiple filters and do some or all of the filtering client-side, or if impossible, request both from the server. The idea that your client can declare what data it needs rather than leaving it up to the server is the best part of GraphQL, the thing that simplified it the most. But it’s hard to do well, right now. It’s much easier to use code-gen directly to have client and server share knowledge of what’s needed. HTTP2 push adds an interesting twist though, when your GraphQL response could actually trigger additional client code and resources to be sent. Of course this can be done without GraphQL, but you’d still need a server that’s aware of what data the client will use and how. For simple APIs or APIs with many clients that behave the same way, GraphQL is overkill. But even so it’s an interesting alternative to simple REST and simple state management, and unlike Redux, you can trigger multiple events at the same time which can be beneficial if processing their state changes at the same time would lead to a more efficient update. (The Redux alternative is to add some kind of wrapper event, or an event for each combination of events...)


> When I reference a Person object in my view that I'm using, will phone number be there or not, who knows.

Well you know, because your view has a query that asks for a Person object with or without a phone number. The cache (your store) is managed by Apollo not yourself.


I theory yes, but in practice react native development seems to be a grab bag of 3rd party libraries and design patterns. Redux, apollo, some typed objects, some untyped objects, stateful wizard views, stateless normal views. Maybe your objects are defined and queried on the view you are looking at, maybe they came from a previous view.


I‘m not talking about theory here but about my professional experience using GraphQL and Apollo for two years in production code. To be specific: I would hardly have a use-case for Redux when apollo-client already has built in local state handling capabilities. Throw in TypeScript and generate your type interfaces from your schema and your queries and there‘s no second guessing. GraphQL and Apollo is not at fault for people writing bad code who mix patterns and ideas that shouldn‘t go together.


"GraphQL and Apollo is not at fault for people writing bad code who mix patterns and ideas that shouldn‘t go together."

When you say this, I hear "Apollo and GraphQL are fragile technologies that don't play well with others."

Furthermore, technical decisions like which libraries to use are many times not at all related to technical reasons like this, but rather what a particular developer with influence wants to do, based on their own personal preferences. OR, the downsides of decisions to use certain technologies are often not understood until problems begin to creep up, and by then it's too late. Of course, technology companies, especially venture backed ones, don't want to highlight those things to decision makers. Either way, I have a hard time blaming the rank and file developers who probably had no input in the first place.


One thing to keep in mind is that GraphQL really supports a different use case than something like gRPC or REST.

One of the places where it really shines is providing a queryable API entry point to a graph of interconnected data. This makes it ideal for generally reusable APIs for consumption by a variety of clients (e.g. GitHub's GraphQL API).

gRPC interfaces are typically use-case specific, and performance oriented (though GraphQL doesn't specify any sort of transport protocol, so you could always serialize GraphQL request/responses with protobufs to gain some performance over the wire), making them well suited for server-to-server communication, but not generally reusable.

REST is resource (i.e. nodes in a graph) based, but doesn't necessarily do a good job of making the relationships explicit and easy to traverse (I'm sure there are good HATOAES implementations out there that address this, but I haven't seen one).

Both REST and gRPC have their place, but I think GraphQL is a clear winner when you want to build a single API to service a large number of distinct clients. It really does offer a clear, easy-to-use API abstraction over where ever you might get your data from.

Also, since you call out code generation specifically; GraphQL provides a strongly-typed schema that can be introspected against, and the tooling to parse queries/schemas into abstract syntax trees. A large number of tools have been built with these capabilities including a number of different code generators. I've even used a GraphQL schema to generate a matching XSD (ugh) for import into an internal business rules engine. Made integration a breeze.


I haven't ever used GraphQL (so take what I say with a grain of salt b/c i could be incorrect), but what gets me intrigued by it is that it helps your engineering organization scale by decoupling the back end and the front end.

Say, for example, that you have a new UI on your app that requires some data stored on your db.

Without graphql, you:

A) Re-use existing REST endpoints and compose data that you need on the front end (but remember that browsers have a hard limit on the number of concurrent api requests. Not to mention that some requests can't be sent until others have arrived back with resource id's). So depending on what endpoints you currently have, this may not be a good option given the latency cost of composing many HTTP requests to get all the required data.

B) You tell your back end devs to create a brand new route that meets the data requirements of the new UI.

With GraphQL, my understanding is that there is zero back end work. You just tell the GraphQL engine what data you need and it magically arrives into your browser.


> With GraphQL, my understanding is that there is zero back end work. You just tell the GraphQL engine what data you need and it magically arrives into your browser.

It doesn‘t quite work like that. Someone still has to implement the backend (resolvers). If you want to request dogs from your backend someone still has to implement the dogs query, but (and I think that‘s one of the greatest things about GQL) as soon as it is implemented, you can introspect your backend and see exactly which properties a dog can have. So you know whether the dog object has a name property, or an isHungry property and so on. So now you can specifically ask for a dog and its name if that‘s all your view needs. Another view might only need the breed, so that‘s what you query for...view specific queries.


It’s understandable that the benefits don’t immediately seem obvious. We have all been working with REST for such a long time that we forgot what didn’t make sense when we were learning REST.

A good way to think about GraphQL is it’s data centric as opposed to operation centric. The unit you work with is the object instead of the operation.

Object level querying instead of operation level querying

Object level auth instead of operation level auth


Wasn’t the whole point of REST that it was object (resource) centric? Not saying graphql isn’t, but there’s not much of a difference in that regard. If anything I’d say graphql is more about the relationships than the objects.

Graphql is more composable for querying, so that’s nice. In terms of mutations, it’s basically just RPC again (and a lot of us missed RPC when REST became popular). And then it has a model for subscriptions, but they still feel a little like second class citizens support -wise at the moment.

None of these are judgements. Just interesting to compare the 2 ideologies.


The main value prop for me with GraphQL is that it makes data a composable, declarative dependency of a view.


So it's a clean abstraction layer? Is that abstraction layer easy to understand, intuitive to train new developers on, and faster to implement then traditional API approaches?


- Easy to understand? Yes, I think so. It's very easy to glean what data requirements a component has from its associated GraphQL query.

- Intuitive? Queries and subscriptions, yes. In the same sense that a React component using props is intuitive. Mutations and optimistic updates are maybe marginally less intuitive, but not prohibitively so.

- Faster to implement? Client-side, absolutely, as there's no need to think about how to retrieve data, you just declare what you want, and Apollo fetches what's necessary. It can also keep track of subscriptions / cache invalidation. Server-side, definitely not. The n+1 problem is tougher than with REST + SQL, and it's harder to make single round trips to the DB to fetch nested data.


There are some libraries that hell with that, namely prisma, hasura and postgraphile.


Completely agree. I think web development is a lot simpler and faster without GraphQL.


My issues with it are 1) I already see enough dumb queries (and queries in indefinitely-long loops...) from backend devs, how will the frontend devs have a prayer of writing performant queries with so much distance from the underlying datastore(s)?, and 2) exposing a highly flexible query language to the frontend, given the variety and complexity of GraphQL libraries and the complexity of implementing GraphQL server-side if you don't just use something that does it automagically for you, sets off my spidey-sense "there will be bad security problems here, sooner or later, guaranteed" warnings.


When will people realize that best practices aren't created by Facebook.


Please don't take this as a personal attack, but I was severely dissapointed with Meteor after being a strong proponent for it for several years.

I advocated for its use on several projects and was bitten by major performance bottlenecks and its over reliance on MongoDB. GraphQL implementation is great, but does it support relational dB's yet?

I am happy to hear that it is still doing well, and I may end up using it for some personal projects.

I believe that the problem it is trying to solve is worthwhile. However I became very frustrated when the push for monetization started while the framework itself still seemed like it was in the prototype phase.

Please correct me if I am wrong, but Meteor has a place in my memory similar to an ex that I really cared about but hurt me once more than I could stomach.


As someone who also jumped on the Meteor bandwagon, and is now stuck maintaining a project created with it, run away and do not look back.

It is not being maintained by anyone as far as I can tell, more and more packages are breaking by the week it seems like, and the basic 'features' listed 'on the box' of Meteor have never worked.

Save yourself some headache and pick a stack with an active community.


1. It is being maintained (albeit less active), version 1.9 is in the works. Communication could improve a lot though.

2. What's so hard about maintaining the Meteor project? It's been mostly backwards compatible since versions before 1.0 (released over 5 years ago, when the JS ecosystem was a very different universe). What other JS framework has a comparible track record towards backwards compatability?

3. Third party packages may break and become unmaintained, but this is just as much true on NPM. In the end Meteor is mostly a build-tool (and a pretty good one, with zero-configuration, code splitting, ...) creating a Node application with full NPM compatability.


I was afraid I would hear that. Best of luck, don't forget to use all your vacation time.


I'm currently using absinthe which enables a graphql backend on the elixir stack with apollo on the frontend. its been working fantasticly well for me so far. Its backed by postgresql and the hardest part so far has been making sure to batch sql queries for complicated graphql queries.

I haven't used apollo-server but I wrote nodejs code for 8 years and I wouldn't trust it to scale without a lot of effort being put into your DevOps story.


Externally, my observation was the monetization of the platform was competing with development. When Galaxy came out, feature work on Meteor slowed down. Hungry VCs wanting their return and rapid growth, I suppose. It would've benefitted more from growing organically longer, before going for monetization.


We love Meteor too, but have been very disappointed by how MDG has seemingly abandoned it. We had so many expectations for things it would be doing by now that never materialized because MDG moved onto other shinier things.


I have experiment Meteor for a while in it early stage, I felt Meteor became complex to manage and didn’t like to stuck in a high technical debts.

Now I would rather wait for V language which seem to solve many limitations found in other languages.


If you don't needed the reactivity, I can see how you could solve your performance problems easier without Meteor. However, if you actually need the reactivity, what other tools/frameworks give you a similar convenient reactivity system with better performance? And there are some solutions within the Meteor community: https://github.com/cult-of-coders/redis-oplog (with some trade-offs)




Registration is open for Startup School 2019. Classes start July 22nd.

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

Search: