Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the notion of partially sharing types between 2 schemas #5951

Open
ychescale9 opened this issue Jun 6, 2024 · 2 comments
Open

Support the notion of partially sharing types between 2 schemas #5951

ychescale9 opened this issue Jun 6, 2024 · 2 comments

Comments

@ychescale9
Copy link
Contributor

Use case

Imagine a monorepo with 2 apps, where each app has its own endpoint and graphql schema.

:schema-1 // graphql schema for app 1
:schema-2 // graphql schema for app 2 
:feature-1-a // app 1's feature module
:feature-1-b // app 1's feature module
:feature-2-a // app 2's feature module
:feature-2-b // app 2's feature module
:app-1
:app-2

We want to build an app-agnostic server-driven UI framework :sdui where we have Composables that depend on some common types in both the 2 schemas:

// common part of the schema for sdui
type Button {
  style: ButtonStyle!
  label: String!
}
enum ButtonStyle {
  PRIMARY
  SECONDARY
  TERTIARY
  DESTRUCTIVE
}

The :sdui module would include graphql fragments:

fragment SduiButtonData on Button {
  style
  label
}

and Composable functions that render the generated fragment:

@Composable
public fun SduiButton(
    buttonData: SduiButtonData,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
   ...
}

The problem is since each schema needs to have its own service, a downstream module (:sdui) would have to choose to use one of the 2 schemas (and service) in order to get the metadata to for generating the code for the fragment, in order to avoid duplicated types from the 2 schemas. This also has a cascade effect where the consumers of :sdui also needs to add the same service / schema as the ones used in :sdui, so if a feature module uses a different schema / service than sdui it would have to depend on both schemas and declare both services, which expose a lot of types and queries that aren't relevant to the feature module and its app.

Describe the solution you'd like

I'm not sure exactly what solution I'd like TBH. Perhaps a mechanism to merge a "synthetic" schema from a 3rd module into both schema modules' services, and also allow a library to depend on the "synthetic" module for declaring fragment and generating code that can be consumed by downstream modules that depend on either schema / service?

I've played with a couple of ideas but didn't get far:

  1. write compiler plugin to add common interface for the SDUI related types, for both schema, so the SDUI library can depend on the interface types, while the downstream feature modules can cast the concrete type to the interface type when using the SDUI components
  2. parse the schema document after downloading either schema (using the tooling artifacts?) and extract the parts relevant to SDUI into a synthetic / stub schema that both schema modules include
@BoD
Copy link
Contributor

BoD commented Jun 6, 2024

Thanks for reporting this. I don't have an immediate idea of what's the best course of action for you (I think maybe the question can be generalized to "how to share code from 2 separate schemas with common types"), but SDUI in general is definitely something we want to keep under our radar.

@martinbonnin
Copy link
Contributor

Quick note: I think my favorite solution there would be a single schema. That would have 2 issues:

  1. you can use “schema-1” types from module “feature-2"
  2. there is some coupling between "feature-1" et "feature-2" (when you reference a new type from "feature-2" , you might end up recompiling "feature-1")

For 1. I wonder if we could use some tooling to restrict types for consumers, potentially based on @requiresOptIn.

For 2., I'm not sure unless we introduce the possibility to generate types in "intermediate" modules compared to today generating all schema types in the "schema" module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants