Open zefhemel opened 3 years ago
I am all-in on this proposal, as I have worked with massive API structures before (for those living in or near germany: the biggest one might be OTTO) which have been transferred to a GraphQL structure. I have seen projects with single and multiple GraphQL endpoints, but as I am not the strongest in back-end technologies and especially performance considerations the actual benefits and downcomes of each are pretty unknown to me.
I'd like to add one item to consider as well: not even the development costs for the server part will be increased, but also (at least initially) the ones for the front-end development, since GraphQL is a whole lot different to what most are used to.
It goes without saying, that, if done right, the performance can be vastly improved by using Apollo (it has its own state management and the overall opinion is, that it can easily replace redux as well - that might be out of scope though) :P
So, I would gladly volunteer to be a active member of this discussion.
I do agree with the Proposal and what @michelengelen mention about the frontend, although when it comes to the front end there are many alternatives, not only Apollo and each front end client can then decide what is the best option for them if this moves forward, some will use Apollo and use it's caching and state management, other will use a library to only perform the GraphQL request and not really use caching or state management (keeping the current state management being Redux / MobX / a local database or whatever).
Yes, this will translate in a ton of work either side, back and front ends but is my believe that will gain a lot from it too, at the very least we should try and build a POC with very limited capabilities and then compare it with what we currently have and then decide if is worth the effort. Also other products like Boards and Playbooks can benefit from this specially cause they are in an "early" stage.
Let's start by saying that I really appreciate this proposal and also think that having it here on Github is a great idea.
I am not going to focus on technical details now but instead I'd like to offer a couple of points that I think we should take into account before making a decision:
Overall, a big +1 on the proof-of-concept, fail-fast approach which is going to be key as I know such endeavour could so easily become a time sink.
As mentioned by @aaronrothschild here one thing we should look into is the permission model and how that's exposed in GraphQL.
@amyblais Could you leave us subscribers a comment in which way this was closed?
Questions I'm asking myself right now:
This is an early-stage proposal. It does not yet go very much into detail on specifics yet. Its purpose is to gather initial feedback on the approach before investing into it more deeply.
Problem
Loading a channel on Mattermost (page load), e.g. the bugs channel in the webapp results in:
Switching between channels uses an additional 18 API calls.
There is a degree of parallelization of these requests, and not every RESTful call results in initiating a new TCP connection (due to connection reuse). Still, even on a fast (home or office) internet connection it is not uncommon that many seconds are spent on performing these requests.
While this may still be acceptable on the desktop, on mobile this becomes much more of a performance bottleneck.
On mobile, network connections...
Analyzing the API calls that our clients make (analysis based on the webapp, but the mobile client uses largely uses the same APIs) we notice a significant number of calls to REST endpoints:
These are used to augment data from other API calls (usually to fill caches). In addition, likely a lot of the data fetched is not actually used (a problem called overfetching).
Why this matters now
We are hard at work delivering v2 of our mobile client. v2 addresses a lot of (client-side) performance bottlenecks. As we eliminate these performance issues, a new performance bottleneck is emerging: the network overhead. Even when running a mobile client locally communicating with a locally running Mattermost instance, the number of API calls that need to be performed slow the experience down significantly.
While we don’t expect to solve this problem before launching v2, we would like to work towards already.
Potential solutions
The problem presented is not unique to Mattermost in any way, many complex applications eventually run into it.
There are roughly two solutions:
Proposal
We propose to add a GraphQL endpoint to the Mattermost server. In effect this would mean adding a single additional endpoint (e.g.
/api/GraphQL
) through which data can be retrieved based on the client’s specific needs (this could be the mobile client, webapp or any other client in the future).To limit the scope of an MVP of this project, we suggest to introduce GraphQL in phases:
And if this is all successful, potentially:
Challenges & Costs
As to any project there is opportunity cost: time spent on building and maintaining GraphQL support could have been spent on other things.
In addition, these are some other things to consider:
Backwards compatibility
While we would not be deprecating the REST APIs, we will have to deal with the fact that the mobile client for some time (likely a year or longer) will have to communicate with Mattermost servers that may not yet have a GraphQL endpoint.
There are multiple ways to deal with this:
Maintenance of multiple APIs
Each new feature will now have to be exposed via REST as well as GraphQL, increasing development and maintenance effort.
Expected benefits
Performance improvement
TODO:
Create a initial GraphQL schema, analyze the requests the mobile client performs on initial load and how those could be translated to one or multiple GraphQL queries.Technical implementation
Implementation of the GraphQL endpoint could be done in at least 3 ways:
Plug-in
In this approach we’d develop GraphQL as a plug-in, likely using a library like GraphQL-Go to expose a GraphQL endpoint and mapping it to internal API calls.
Pros:
Cons:
mattermost-server
and migrating it into the main server may be a lot of effort?Apollo server wrapper
The approach would be to deploy Apollo Server alongside Mattermost. Apollo server is a node.js-based product. We would expose the GraphQL endpoint separately (perhaps mapped into our regular API namespace via nginx proxying) and in the GraphQL resolvers defer calls to our existing RESTful APIs.
Pros:
Cons:
In mattermost-server directly
In this approach we’d add GraphQL directly into our mattermost-server API, likely using a library like GraphQL-Go to expose a GraphQL endpoint and mapping it to internal API calls.
Pros:
Cons: ?
Discussion
We have a dedicated ~GraphQL Discussion channel on the mattermost community server.