Reimplement REST API in terms of GraphQL API
Problem to solve
GitLab is gearing up its GraphQL API: &711 (closed)
It's expected that this will eventually expose everything the REST API has, and more, but at present the two APIs use completely separate entities and query implementations. This means that as the graphql API gains scope, we will be maintaining two completely separate implementations, and more and more, a change will require us to duplicate work. The larger the graphql API is, the more this becomes a problem.
Target audience
GitLab developers looking to add features
Proposal
Reimplement REST API endpoints so that they execute a graphql query instead. The result of that query should be identical to what the REST API returns - or as close as possible. Instead of having a specific REST API entity, we can then just pipe the response back to the requestor.
One very trivial example is the GET /api/v4/version
endpoint that currently exists in the REST API. Rather than duplicating the (admittedly very simple) logic, we could instead add the endpoint to graphql, then replace the existing code in lib/api/version.rb
with a simple hardcoded graphql query that will return JSON that satisfies the existing contract. Now the logic for that endpoint is only in a single place.
The benefits of doing this, as I see it, are manyfold:
- Reduced code
- Maintaining multiple independent entity classes is going to be pain
- Adding complex fields means we have to duplicate the logic
- Forces honesty in the GraphQL implementation
- GraphQL equivalents for the affected endpoints has to serve all existing use cases
- It forces us to consider backward compatibility more carefully, as the REST API becomes a comprehensive graphql client we maintain
- Improved performance in the REST API
- GraphQL queries can be more efficient than what we're doing at present
- Existing REST users get some benefit without needing to change to graphql
- Pushes graphql implementation along
- Anyone wanting to add to the REST API must do so in the graphql API, then update the graphql schema for that REST endpoint. So GraphQL always keeps up to date.