smallrye-graphql icon indicating copy to clipboard operation
smallrye-graphql copied to clipboard

Add support for federation

Open phillip-kruger opened this issue 4 years ago • 58 comments

Might be a lot of work, but let's consider support for federation

https://www.apollographql.com/docs/federation/managed-federation/overview/

phillip-kruger avatar Nov 18 '20 10:11 phillip-kruger

Thanks Phillip, I think Federation support would be really helpful given organizations adopting microservices pattern. Especially with large organizations with varied technology stacks who want to have a single unified data graph combining multiple microservices on different technology platforms.

There is already a support for federation on the JVM via apollo federation-jvm package. Probably worth looking if that can be leveraged here?

chet20r avatar Nov 18 '20 11:11 chet20r

This is about services taking part in a federation, right? Writing a federation gateway is a completely different and much bigger topic. I've read several blogs and watched several talks trying to understand esp. the difference between Schema Stitching and Federation. For me, this blog post explained it best.

My ultra-short summary: Schema Stitching works with custom code in the Gateway that hooks the endpoints together. While this approach starts very simple, complexity grows exponentially, as there is a single point that has to know about all connections. Federation OTOH distributes this responsibility to the separate services, e.g. a user service only knows about the User type, while a review service extends the User type with a reviews: [Review!]! field while only knowing about the id of the user. This and a few more things is done with quite flexible directives; and the gateway then does all the Federation magic on a generic level.

t1 avatar Dec 27 '20 08:12 t1

Maybe it would be sufficient to create a separate library like smallrye-graphql-federation that contains the required types and some custom directives (#628)? Then the core engine nor the spec wouldn't need to know about federation... which currently is actually quite Apollo-proprietary, or is there any other implementation of the gateway?

t1 avatar Feb 03 '21 16:02 t1

The correct link to start from is https://www.apollographql.com/docs/federation/federation-spec/

The managed-federation link in the description is about the advanced federation gateway in the Apollo Studio product that manages the services with a registry instead of having to list them manually before startup of the gateway.

t1 avatar Mar 21 '21 07:03 t1

I found that if we really want to support federation with an extension (i.e. a library you can include, not something built directly into the server implementation), we not only need custom directives (#628 for @external, @key, @provides, @requires, and @extends), we also need:

  • Unions (#400 for _Entity); this even has to be dynamic, as the union is the list of all types with a @key directive.
  • Custom scalars (MP#94 for _Any and _FieldSet); _Any is a complex scalar (which is an oxymoron in my eyes).

t1 avatar Mar 21 '21 13:03 t1

I've started some experiments and pushed them here. There are many prio A TODOs left, but it works as a PoC!

I'd love to hear your feedback.

t1 avatar Mar 24 '21 16:03 t1

Thanks @t1 ! I'll have a look a.s.a.p

phillip-kruger avatar Mar 29 '21 15:03 phillip-kruger

As mentioned in the meeting yesterday, there is one major issue open: a type used as a @FederatedSource argument is not automatically added to the schema, so as a workaround I have to define something like @Query public Film dummyFilm() { return null; }.

t1 avatar May 27 '21 03:05 t1

It could be possible that #312 could help to fix this last priority A todo.

t1 avatar May 27 '21 03:05 t1

Can we maybe discuss here (again) why can we not use @Source ?

phillip-kruger avatar May 27 '21 07:05 phillip-kruger

why can we not use @Source ?

You mean instead of @FederatedSource? I actually haven't thought about that before. It could work and fix the problem with registering the type. But we'd have to replace the local resolver logic. I'm not sure how to do that.

t1 avatar May 27 '21 08:05 t1

Yea, so the class needs an @External right ? So we should be able to figure it out, but it might need some changes in SR impl module

phillip-kruger avatar May 27 '21 08:05 phillip-kruger

What is current status for the federation support? Can I use it with quarkus in expiremental/alfa status on my own risk? There are still no federation quarkus extension #15386.

mistreckless avatar Jul 28 '21 10:07 mistreckless

It currently works as an alpha in JEE containers, but not in Quarkus. We're still working on the Quarkus Extension, but there was not much progress lately. Do you want to support?

t1 avatar Jul 28 '21 13:07 t1

@t1 I would really like to help with the Quarkus extension, where can I start from?

shmulik-klein avatar Jul 31 '21 11:07 shmulik-klein

Maybe @phillip-kruger can give you a hint?

t1 avatar Jul 31 '21 12:07 t1

I'll be honest - I am not sure. I am not sure if this would be a new extension, or build into the current one. I think the current one. So maybe start by playing around with that ?

phillip-kruger avatar Aug 03 '21 17:08 phillip-kruger

Thanks @phillip-kruger.

@t1 @phillip-kruger Just to make sure that I understand it correctly - quarkus-smallrye-graphql Quarkus extension, generates the graphql schema at build time (Augmentation), so it can't work with smallrye-graphql-federation-runtime as the later observes to the schema creation and adds to it the entities required to make it a federated schema? - meaning, you can only use it entirely as a Quarkus extension or entirely as a regular dependency, but can't make a mix of those?

Also, isn't the extension resides on quarkusio/quarkus repository?

shmulik-klein avatar Aug 04 '21 08:08 shmulik-klein

Another small question (+@t1), is it possible to use smallrye-graphql + smallrye-graphql-federation-runtime dependencies on quarkus to get graphql federation support? I tried to do so with undertow + smallrye-graphql-servlet, but failed. I tried to do so to better understand the bootstrapping logic.

shmulik-klein avatar Aug 05 '21 12:08 shmulik-klein

@shmulik-klein @t1 - I think we said that we should merge the federation stuff (in SmallRye) into the smallrye-implementation. That means we need to move the annotation discovery to the common/modelbuilder module. That way, quarkus should just work

phillip-kruger avatar Aug 05 '21 13:08 phillip-kruger

My intuition was to combine the extensions, but this sounds better. I'll look into that.

shmulik-klein avatar Aug 05 '21 13:08 shmulik-klein

Please note that the main thing missing is tests. They'd have to live in the SmallRye TCK.

We also talked about using the @Source annotation instead of the @FederatedSource, which might let us get rid of the requirement to declare federated types as a query result in order to use them as a federated source.

t1 avatar Aug 06 '21 05:08 t1

@shmulik-klein: It would be cool if you could share your progress as early and as often as possible in a PR, as I need this, too.

t1 avatar Aug 07 '21 04:08 t1

@t1 I had to overcome the following issue #963 to be able to run the maven plugin and to better understand the schema-builder flow. I understand that the schema builder generates a io.smallrye.graphql.schema.model.Schema, while the Federation's code acts on graphql.schema.GraphQLSchema.Builder. In order to integrate it into common/schema-builder should I refactor Federation to act on Schema or is there a better way around?

Also, Federation relies on CDI, while for example, the maven plugin doesn't provide such, do we also want to remove the CDI dependency from Federation?

I'll try to get a PR asap, but I'm still trying to understand the flow and the right way to integrate it.

shmulik-klein avatar Aug 08 '21 09:08 shmulik-klein

I haven't thought about this earlier. The existing federation module was planned as a "plugin", so it does everything at runtime. When integrating it into the core module, there are some static parts (_service and _entities) and some dynamic parts that depend on the other types used (_Entity).

I think we need a config option to enable it.

Creating a PR is helpful to have code to discuss about, even when it's still completely in progress. You can mark the PR as explicitly "draft".

t1 avatar Aug 08 '21 09:08 t1

I'll try another approach based on https://github.com/apollographql/federation-jvm. Our code will only have to scan for the annotations and add them to the schema, while this lib does all the necessary schema transformation and resolution.

I'm curious to see how this works out.

t1 avatar Oct 24 '21 08:10 t1

Hello @t1, I'm willing to use Quarkus + graphql and federation in a project.

So, just let me know if there's anything that I can do to help collaborate with this feature, such as coding, testing, or even updating the documentation.

emmanuelsilva avatar Oct 26 '21 14:10 emmanuelsilva

@emmanuelsilva: that's great to hear. Just out of curiosity: what Federation server do you plan to use?

t1 avatar Oct 27 '21 20:10 t1

Hi @t1, at the moment, we are thinking about using the apollo gateway, but we are still trying to find one gateway that runs on top of the JVM.

It might be a good feature to have a federation server on top of smallrye-graphql.

emmanuelsilva avatar Oct 28 '21 14:10 emmanuelsilva

@emmanuelsilva: Then you might be interested to know about the federation server we started to write in 100% Java. It's yet still in a PoC/experimental stage, but I would be glad to get some help. https://github.com/graphql-feder/feder

t1 avatar Oct 29 '21 12:10 t1