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

[FerryGenerator]How to make it work within a monorepo? #531

Open
letsar opened this issue Aug 16, 2023 · 6 comments
Open

[FerryGenerator]How to make it work within a monorepo? #531

letsar opened this issue Aug 16, 2023 · 6 comments

Comments

@letsar
Copy link

letsar commented Aug 16, 2023

Hi!

First of all, thanks for this suite of packages.
We are using Ferry within a monorepo and using ferry_generator to generate the models. We would want to have each graphQL query in the dedicated package, it works well, but we need to have the schema in each packages and thus, all the generated code for the schema is duplicated in each package.

We would want to have the schema in a dedicated package and be able to only generate the models of the schema in this package and not in the other ones.

Did I miss something or it's not possible for the moment?

@letsar letsar changed the title [FerryGenerator]How to make it work within a monorepo [FerryGenerator]How to make it work within a monorepo? Aug 16, 2023
@knaeckeKami
Copy link
Collaborator

Hi! Nice to see you over there!

Yes, you are right, this is not possible at the moment.

But I think it should be relatively easy to implement. Will take a look.

@knaeckeKami
Copy link
Collaborator

Well, actually it's not that simple.
Currently there is the assumption that there is a Serializers object that knows how to deserialize any OperationRequest without type hints (i.e. for the offline mutation link), this might break with a multi module approach.

@letsar
Copy link
Author

letsar commented Aug 17, 2023

Hi thanks for taking the time to look at this.
I don't have the time right now to make a POC, but maybe in a few weeks. I have a few ideas. Let me know what you think.

  • One package would be responsible for generating the models for the schema and the serializers.
  • I think we would still need to have the schema in every package (or at list a symbolic link) for the graphql_builder to work.
  • We could have an option in the build.yaml file to specify the imports for the schema models and the serializers, so that we could use them in the generated code for the queries. If null, we would consider that the schema models are in the same package.
  • Maybe we could remove the serializer_builder from the build.yaml for the packages which don't generate the models for the schema.

@knaeckeKami
Copy link
Collaborator

A single package for the schema & the serializers would not work, I fear.

If we have a single package for the schema, and N feature packages that contain operations (queries, mutations, subscriptions), the feature packages need to depend on the schema.

But the serializers need to know both the schema and the operations, so this would cause circular dependencies.

I think a way to solve this would be:

  • have a schema package that every feature package depends on. The schema package generates the .schema.gql.dart file and a Serializers class, but just for the schema types (e.g. scalars, enums, inputs).

  • feature packages depend on the schema file and import the generated .schema.gql.dart file instead of generating their own. They also generate their own Serializers class and merge it with the Serializers (https://pub.dev/documentation/built_value/latest/serializer/Serializers/merge.html ) from the schema in order so ensure that they can fully serialize all required types.

  • optional: when required (e.g. for persisting mutations when offline), add an additional package that depends on the schema package and all feature packages. This package merges all the Serializers so we can again serialize and deserialize all types with a single object.

This might sound pretty scary, but I think all of this is doable with relatively small changes to the code.

In fact, I hacked together something that already does most of this here: https://github.com/gql-dart/ferry/pull/533/files

This would allow specifying the schema from another package and prevent code generation for the schema when passing generate_schema : false to the build.yaml, importing it instead.

@meg4cyberc4t
Copy link

Hi. I see you haven't written anything for a long time. Are there any updates?

@knaeckeKami
Copy link
Collaborator

#606 was merged and ferry_generator 0.12.0 was released.

A caveat is still, that OfflineMutationTypedLink won't work, because there's no single Serializers class which could deserialize any requests

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

No branches or pull requests

3 participants