At my last job, we were building a social shopping app. Behind the scenes, products were versioned so that we could deal with disputes related to attempts to defraud customers. This (along with several other things) meant that the logical internal abstraction of the data model for things like dispute dashboards was considerably more complicated compared to an abstraction that made sense for the clients (apps and website).
If we only had one graph, all the clients developers would have to develop around a data model that was far more unwieldy than they needed. But with two graphs, the world was a lot simpler (at the cost of having to maintain two graphs).
I'll never forgive them for taking a great concept and absolutely beating it to death with intellectual (for lack of a better word) wankery. We could have ubiquitous Datomic style triple stores today if not for the Semantic Web researcher's need to generate pseudo-academic journal articles.
Let’s say in your internal model there’s a relationship A - B - C. But for client apps it makes no sense to expose B, so instead you choose to represent the model as A - C. This is more than just a simple subset. Someone who understands graph theory better than I may be able to explain if there are elegant approaches to this.
I can see the argument if you have a web frontend that consumes data from multiple backend services – have one GraphQL service that manages them all instead of a GraphQL layer on each service.
But this breaks down greatly when you have different "Viewers". In a web app, the "Viewer" can be a logged in user. In an admin dashboard, the "Viewer" is very different – an employee acting on behalf of users. Service to service communication likely doesn't have a concept of a "Viewer".
I would propose that you have different schemas when you have these different views of the world or different permission boundaries. The business logic can be shared – you may just enforce different authorization checks at the GraphQL layer. You could also share GraphQL types that are common between schemas.
Not only do these end up with very different data models, but they are also likely to have different access control (customer facing is basically all open, scoped to user, internal has many different layers and permissions), it’s likely to have different performance concerns, reliability, etc. That’s a lot of complexity you don’t need slowing you down when you’re building the other graphs.
You have one root, but mutiple nodes after that, every one being essentially another graph.
I'm using GraphQL in production systems. One is Node (graphql-js) and another is Java (graphql-java.) I read the GraphQL specification and adopted the reference implementation and it works great. Am I missing some enormous value by naively just using GraphGL without involving Apollo?
That is a sincere question. What is the deal here?
This piece, while somewhat valuable, is largely content marketing. First they sell you on the idea of "best practices." Then they'll follow up w/ a tool that, surprise, does all those "best practices" for you. "The modern marketer creates their own demand." Prisma is another GraphQL company that produces content like this.
[0] Relay has its own spec and can be used only if the server supports it. Other GraphQL clients are either not well maintained or do not support as many features as Apollo does (caching, subscriptions are two features that come to mind)
They're also intending to make most of their money by promoting GraphQL as a tool, so low rates of adoption are an existential risk for their company, while Facebook only needs GraphQL as a PR and recruitment tool.
But I'm not going back to a world without data-masking at the component level, so Relay is the only choice for me right now (though I wish it wasn't).
Apollo Server is an improvement over baseline graphql-express, but for the most part it's nothing you can't easily add yourself. Having compatibility with Apollo Engine is useful if you end up wanting to use their monitoring tools. Pretty much everything else is just down to how much you want to buy into their ecosystem.
The client side depends on the client, we have a Angular SPA that extensively uses Apollo Client together with some code generation tools. The benefits we see from this are:
* The whole schema is automatically defined in frontend, so it is easy to keep types in sync between frontend and backend. * .gql files are scanned, so services that consumes the queries/mutations are automatically generated with correct typing. * The Apollo Client cache makes it easier keep the data updated across different components.
This greatly reduces the boilerplate code our developers have to create, and it makes it much easier to share type definitions from backend to frontend without having to worry about them getting out of sync. We are still exploring different tools, to see what we might benefit from.
2. Marketing aside, they are one of the very few (if any) solutions that provide tools that fill the glaring gaps in GraphQL and make it easy(-ish): caching, auth etc.
I see it's advantages of having auto-documentation for each API. Thumbs up here.
Having said that, the amount of hoops one has to jump before completely adopting it - makes it 'meh'. There are lot of things : cache (clien-and-server), n+1, apollo (why?), deeply nested queries, schema stitching. The amount of patch work one needs to learn is not worth it.
I disagree. GraphQL is more difficult to implement than "bad REST", but probably easier to implement than "good REST", partially because there's very little tooling around good REST implementations.
If you just want JSON over HTTP with some status codes, then sure GraphQL is loads more work, but that's definitely not REST.
The innumerable patches/packages trying to fix what GraphQL lacks - goes to show it's a good idea at surface level yet poorly thought out from ground up.
yes this
Qualifier: have not been able to use graphql yet, and I'd still like to try it out at least before making and judgements
We have multiple "gateways" for multiple backend services.
We have our main application that has one graph and we have multiple internal applications each owns its own graph.
I don't think the main application needs to know about the other internal graphs, nor should it have access to it (it should not even discover it).
* Non-GraphQL services (speaking REST, gRPC, whatever) * GraphQL gateways, owned by frontend teams/applications.
E.g. each frontend team/application owns its own schema owned by these teams. They can compose the backend services however they wish—and whatever is the most natural representation for their domain.
Am I missing something here? Has this been addressed?
Thanks.
I think 'One Graph' makes sense if that's how you model your data under the covers (e.g. Facebook's graph store)—but if you're in a service-laden world, it makes far less sense.
You can't control malicious clients so I don't think the access part holds much water.
I think they are advocating a monolith deployment to maintain contracts across ownership and client expectations as a best practice vs the version management of multiple graphs requiring different cross sections of data for each client. It helps keep it consistent.
my 2 cents
We don't use a mono-repo, we use a repo per service.
We have shared libraries like https://github.com/globality-corp/nodule-graphql that make generating gateways easy and straight forward.
I haven't done anything with GraphQL in a few years. But when I did, we basically had several teams in a part of our organization (one of many in a huge giant megacorp) which built an API with GraphQL. We shared that code base and did the changes in it we needed for different parts of the graph. Sometimes it was fine, and sometimes it didn't go so well (unexpected issues, unexpected deployments when a team didn't prepare properly, etc). So it was an OK idea, but it caused some friction.
A decent of the problems were communication between teams of course. But even if communication was as good as one could imagine, it seems like this model would cumbersome at some point. And I can't imagine it spanning our entire organization, much less our entire megacorp across the board.
So assuming what we did wasn't good, what is a way you might make this work? Do you have a single code base like we did and just be more disciplined? Do you have a project whose job is to stitch together other schemas and pull in submodules? A monorepo for the entire company? Do you actually limit what the idea of the company is at some point to limit what the scope is that this should cover?
This turned out to be more of a ramble than anything. Oops.
> So assuming what we did wasn't good, what is a way you might make this work? Do you have a single code base like we did and just be more disciplined? Do you have a project whose job is to stitch together other schemas and pull in submodules? A monorepo for the entire company? Do you actually limit what the idea of the company is at some point to limit what the scope is that this should cover?
I think these are great questions. One approach that looks promising is the idea of modular schemas that can be stitched together into a larger graph. Quite a few large organizations are doing this now. I recommend watching a recent talk by Martijn Walraven for more on this idea: https://www.youtube.com/watch?v=OFT9bSv3aYA
The old way required a lot of manual work to pull in the different service schemas and do the stitching by hand. Luckily the team at Apollo and others are working on a new approach that automates a lot of the old work.
Shameless plug: I wrote a blog post that goes into some detail about what this can actually look like if you want to see more: https://medium.com/@aaivazis/a-guide-to-graphql-schema-feder...
I'm using GraphQL in production since 2015 and I feel like the only Apollo contribution to the ecosystem was pushing lot of marketing content around their hacky tools and "best practices", leading teams to poorly designed backends.
They supposedly have a slightly different recommended way of doing the things Relay tries to do, but it's poorly documented and only compatible with Apollo, whereas the Relay spec is relatively clear (just the spec, I haven't used the Relay library).
Also they seem entirely JS focused. Our backend is Python and our frontend so far is Swift. They have no Python tooling, and their Swift codegen has a lot of issues, our iOS devs use it pretty reluctantly and replace a lot of parts of it, and even that tooling is all in JS, not Swift, which means our iOS builds suddenly need Node, Yarn, NPM, etc, a whole load more complexity, caching, and so on.
There are definite difficulties to doing this, you need some strong cohesion between teams. If you try to do it in an agile manner, you're going to end up with a lot of duplication with minor differences. You'd need a way to flag existing similar data when trying to add new branches and nodes.
Our hope is to make our graph explorable and interactive so teams we don't have direct contact with, often in other countries, are able to find the data they would be interested in and see immediately how to read it out.
Independent team structures and microservices based architectures are acknowledging that such monoliths are impossible to build and maintain.
Federated implementation. Implementation being spread across many teams is important, but if that is through federated services being reused by multiple teams, it can create brittle dependencies.
Track schema in the registry: It's difficult to have a single source of truth when it is unable to display the variation based on #1 comment. I don't think anyone has solved this well for really large systems. Good principle but hard in practice!
I think it is really hard for a VC backed company selling a product to describe principles without being biased. This feels very biased toward selling their product.
I wonder about the other proposal for demand control, namely that untrusted users "should only send queries that have been preregistered by the authenticated developer of the app". To me, that seems to somewhat negate a great advantage of GraphQL, namely giving clients more flexibility in deciding (on the fly) what data to fetch/mutate.
For some reason I found this very simple scenario quite a hassle using a native GraphQL client for Android. And the alternative, ditching the client and making simple http requests was rather clunky when poking around what's returned.
Admittedly I only spent an hour or so on it but...REST just seems drastically simpler to get up and running with.
At its core, it is a project based around a _consumer facing schema_, that can be queried. You put in upfront and ongoing be work to give product/frontend/clients the ability to discuss data requirements around a first-class schema, and then once the resolvers are written, allow them to explore/experiment with the data, in queries that can be used directly in production.
From what I have seen, the first (only?) ones to feel the pain it solves for are Product/Frontend/Clients.
Hopefully that ^ waves away some of the haze
Apollo Client makes a lot of things about frontend apps easier, which is possible because of the well-defined and typed interface that graphql enforces. No, you don’t need it, and there are other ways (like maybe using Swagger) that you could get similar typing for a REST interface. But, FWIW I’m not familiar with any tools that are quite as comprehensive as Apollo out of the box that don’t use graphql.
If you want to have a united interface to multiple services behind the scenes and incorporate ACL or any kind of top-level resource management, GraphQL is a great way to go about doing that.
I like GraphQL outside of these points as well because it's more opinionated than REST. It means you can get on with things instead of having long disagreements about what is and isn't RESTful.