smallrye / smallrye-graphql

Implementation for MicroProfile GraphQL
Apache License 2.0
160 stars 92 forks source link

Handling federation _entities queries without creating @Query #2180

Closed RoMiRoSSaN closed 1 month ago

RoMiRoSSaN commented 2 months ago

See #2110

RoMiRoSSaN commented 2 months ago

I found this #1585, #521 Here how I understand was annotation FederationSource, but now smallrye graphql not contains it. The logic there intersects with my PR. For example, in NodeJS federation router itself sends requests about what and what fields it needs. And there it can be any object (list of parameters). At the moment I have not yet come up with how creeate a universal wrapper object (method must have all required 'primitive' params. see test). With these changes, the router can obtain the required data. And most importantly, queries are not published to the schema. Exmaple, service extends external type other service

extend type Type key('id') {
  id: String external
  name: String external
  value: String requries('name')
}

If you request a field value will be sended request like

_entities(representations: { id: "id", name: "name", __typename: "Type" }) {
  __typename
  ... on ExtendedType {
    value
  }
}

value extended field. It turns out you need to make 2 requests, by id (default and may be query), and id and name (value requires field name). And if you publish so many queries to the schema, it can become very large. And it may not be necessary for requests to be available exclusively to the federation router. It can be useful only for federation

RoMiRoSSaN commented 2 months ago

It would probably be nice to have such an option.

record Vars(String id, String name){}
@Resolver
Product find(Vars vars){
   ...
}

and allow pass queries like

_entities(representations: { id: "id", name: "name", __typename: "Product " }) { __typename  ... on ExtendedType { id name value } }

_entities(representations: { id: "id", __typename: "Product " }) { __typename  ... on ExtendedType { id} }

in one method. or maybe it is wrong idea.

RoMiRoSSaN commented 2 months ago

Unfortunately, I couldn’t figure out how to make one general type. Too much magic

Needs simple changes in quarkus (add resolvers operations here)

RoMiRoSSaN commented 2 months ago

Hi @jmartisk, @t1. What do you think about it? For example, This example in JS. And in Spring

jmartisk commented 2 months ago

Hi, sorry a bit busy, but I'll try to review at the beginning of next week...

RoMiRoSSaN commented 2 months ago

This will require changes that are present in https://github.com/smallrye/smallrye-graphql/pull/2184

RoMiRoSSaN commented 2 months ago

@jmartisk Hi. I’ve probably already tired you, but please look at this PR too. In short, this will allow to avoid creating a bunch of @Query for federations, while calmly expanding the types. For example, there is a service users that implements the User type. There is a status-user service that extends the User type with the blocked field. With the current approach, in the second service requires creating @Query which will be displayed in the general schema, although such a request may not carry any logic separately.

For this PR, it also wouldn’t hurt to add quarkus to the @Resolver index (in the same branch that you did for 2.11. I can do it later when we discuss this PR)

jmartisk commented 1 month ago

Ok, would you also please create a PR to my Quarkus branch (https://github.com/jmartisk/quarkus/tree/smallrye-graphql-2.11) with the Quarkus-side change and preferably also a simple test that runs with Quarkus?

RoMiRoSSaN commented 1 month ago

Added changes and a couple of simple tests to your fork and create PR. After accepting the PR for quarkus, need restart the pipeline here, to be sure everything is ok.

jmartisk commented 1 month ago

Ok, merged the Quarkus part, now re-running the CI here... Thanks!

RoMiRoSSaN commented 1 month ago

@jmartisk It seems like I did everything, made all the necessary corrections.

jmartisk commented 1 month ago

Thanks!