Reputation: 1115
I work on a project that uses a single GraphQL schema to expose data from REST APIs to various clients. The schema design is "owned" by the front-end teams, and is shaped to represent the universe as they see it. This neatly decouples the UI from the API tier, and is working fairly well. Some (poorly designed but essential) APIs are relatively complex, and require domain knowledge (aka business logic) to compose the data into a form that maps to the UI schema, but that business logic is changing, as legacy APIs are pulled apart and rewritten - the problem therefore is twofold:
I am considering introducing a second GraphQL instance that acts as the domain model, which will be owned by the API teams, and abstracts the details of how to call each API, and compose raw data to be consumed by the UI schema. It does introduce a small performance overhead, but on the plus side, decouples the Schema from the API implementation detail.
In researching this approach I have not found examples of this being attempted elsewhere so wondered if I'd missed any, or if this represents an anti-pattern that should be avoided?
Upvotes: 12
Views: 245
Reputation: 4269
It seems that your additional layer would move the problem around, but not solve the root issue.
As mentioned in some comments, the best way to solve this depends on the organization itself. Moreover, some organizational changes might be needed to avoid madness.
Teams currently owning the business logic and internal APIs are clearly upstream (as defined in Vernon's Implementing DDD) from the UI teams, and that is fine. But then, API changes need to be communicated actively, and APIs would likely need versioning in these cases.
GraphQL should be an implementation detail of your API gateway after all, and as such, it should stay replaceable by whatever is cool next, even if you don't plan on changing it.
If you also need to process data in a way that requires business logic (and even worse, to maintain state) because this "universe as they see it" is quite different from what you get from upstream; This exceeds the gateway pattern and it is a problem of its own. A separate component, the smaller the better, can be deployed in between the REST APIs and your gateway to address this, but this component would be a first class citizen and not just some glue code. There would be little benefit in this component/service to serve GraphQL; It would only have one client, your existing gateway.
If your backend REST APIs only serve this data for the UI, but the UI can't use it like that, then "it's a people problem" that needs to be solved first.
Upvotes: 1