Search code examples
restgraphgraphqlarchitectureapi-design

Multiple Presentation Layers over single service


The question is pretty straightforward, is it possible to have multiple presentation layers working on the same service? E.g: have a REST API for applications that mostly do CRUD operations with the data and a Graph API for clients that would benefit from fetching data according to their needs. The inspiration for this question comes from a diagram (below) that appears in the docs of GraphQL.

GraphQL architecture diagram

In this diagram the Presentation Layer takes whatever form while using the same Business Layer and subsequently the same Data Access Layer. While I assume this is usual (I might be wrong), I haven't found any resources on the internet explaining what is common practice.

I am currently trying to build a Graph and a REST within the same application, I don't know if this is industry standard or it would be to have each Presentation Layer access another service thus having three separate applications (one packaging business layer + data access layer and one for each presentation layer).

It is worth mentioning that I haven't worked with GraphQL previously (only REST APIs) and there might be some kind of obvious impediment that I do not know about.

Thanks in advance.


Solution

  • When I'm thinking about such questions I usually try to find out either "reference architecture" for my tech stack or discover how other companies solve similar problems.

    E.g. I for examples of well defined API I usually refer to GitHub API. GitHub has both REST and GraphQL API. I can assume that resources exposed via both API are the same - branches, pull requests, commits etc. In you app you probably also have some data/entities exposed via API. I can imagine at least those will be the same and you can reuse them.
    Probably it would be interesting for you check our their migration guide https://docs.github.com/en/graphql/guides/migrating-from-rest-to-graphql They say :

    The differences between REST as a style and GraphQL as a specification make it difficult—and often undesirable—to replace REST API calls with GraphQL API queries on a one-to-one basis

    At this point it seems that having 3 different applications which sharing same data models for every Presentation Layer is an option.

    Then let's check "reference architecture". I'm from .net world and for me it's https://github.com/dotnet-architecture/eShopOnContainers#net-microservices-sample-reference-application. If I look in Ordering microservice I see that it has both REST and GRPC API provided :

    [Orderting API][1] [1]: https://i.sstatic.net/zkAS8.png

    That's achieved by structuring application using Clean Architecture approach. For my .net stack pretty good intro is given here, but the concept is applied for any programming language: https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures#clean-architecture The core idea is following :

    Clean architecture puts the business logic and application model at the center of the application. Instead of having business logic depend on data access or other infrastructure concerns, this dependency is inverted: infrastructure and implementation details depend on the Application Core. This functionality is achieved by defining abstractions, or interfaces, in the Application Core, which are then implemented by types defined in the Infrastructure layer.

    To sum up I would say following:

    • you don't need to have 3 separate application for every Presentation layer
    • define interfaces in the Business Logic layer and make Presentation depend on interfaces
    • it could be that e.g. for REST and GraphQL you might need sometimes different interfaces defined because the whole concept of accessing data is different
    • even if you have different interface they operate with same data models defined in your Business Logic layer(Core)
    • it quite possible that different interfaces implementation (e.g. let's call them RestQueryService and GraphQlQuery Service) will use same interfaces of your Persistence layer.