title: Problems integrating Python graphene with Apollo Federation
body: <p>Using python to implement GraphQL across multiple microservices, some use Ariadne, and some use graphene (and graphene-Django). Because of the microservice architecture, it's chosen that Apollo Federation will merge the schemas from the different microservices.</p>
  
  <p>With Ariadne, it's very simple (being schema first), and a small example:</p>
  
  <pre class="lang-py prettyprint-override"><code>from ariadne import QueryType, gql, make_executable_schema, MutationType, ObjectType
  from ariadne.asgi import GraphQL
  
  query = QueryType()
  mutation = MutationType()
  
  sdl = """
  type _Service {
      sdl: String
  }
  
  type Query {
      _service: _Service!
      hello: String
  }
  """
  
  @query.field("hello")
  async def resolve_hello(_, info):
      return "Hello"
  
  
  @query.field("_service")
  def resolve__service(_, info):
      return {
          "sdl": sdl
      }
  
  schema = make_executable_schema(gql(sdl), query)
  app = GraphQL(schema, debug=True)
  </code></pre>
  
  <p>Now this is picked up with no problem with Apollo Federation:</p>
  
  <pre><code>const { ApolloServer } = require("apollo-server");
  const { ApolloGateway } = require("@apollo/gateway");
  
  
  const gateway = new ApolloGateway({
      serviceList: [
        // { name: 'msone', url: 'http://192.168.2.222:9091' },
        { name: 'mstwo', url: 'http://192.168.2.222:9092/graphql/' },
      ]
    });
  
    (async () =&gt; {
      const { schema, executor } = await gateway.load();
      const server = new ApolloServer({ schema, executor });
      // server.listen();
      server.listen(
        3000, "0.0.0.0"
        ).then(({ url }) =&gt; {
        console.log(` Server ready at ${url}`);
      });
    })();
  </code></pre>
  
  <p>For which I can run graphql queries against the server on <code>3000</code>.</p>
  
  <p>But, with using graphene, trying to implement the same functionality as Ariadne:</p>
  
  <pre class="lang-py prettyprint-override"><code>import graphene
  
  class _Service(graphene.ObjectType):
      sdl = graphene.String()
  
  class Query(graphene.ObjectType):
  
      service = graphene.Field(_Service, name="_service")
      hello = graphene.String()
  
      def resolve_hello(self, info, **kwargs):
          return "Hello world!"
  
      def resolve_service(self, info, **kwargs):
          from config.settings.shared import get_loaded_sdl
          res = get_loaded_sdl()  # gets the schema defined later in this file
          return _Service(sdl=res)
  
  schema = graphene.Schema(query=Query)
  
  # urls.py
  urlpatterns = [
      url(r'^graphql/$', GraphQLView.as_view(graphiql=True)),
  ]
  </code></pre>
  
  <p>,... now results in an error from the Apollo Federation:</p>
  
  <h2>GraphQLSchemaValidationError: Type Query must define one or more fields.</h2>
  
  <p>As I checked into this matter, I found that apollo calls the microservice with a graphql query of:</p>
  
  <pre><code>query GetServiceDefinition { _service { sdl } }
  </code></pre>
  
  <p>Running it on the microservice via Insomnia/Postman/GraphiQL with Ariadne gives:</p>
  
  <pre><code>{
    "data": {
      "_service": {
        "sdl": "\n\ntype _Service {\n    sdl: String\n}\n\ntype Query {\n    _service: _Service!\n    hello: String\n}\n"
      }
    }
  }
  
  # Which expanding the `sdl` part:
  type _Service {
      sdl: String
  }
  
  type Query {
      _service: _Service!
      hello: String
  }
  </code></pre>
  
  <p>and on the microservice with Graphene:</p>
  
  <pre><code>{
    "data": {
      "_service": {
        "sdl": "schema {\n  query: Query\n}\n\ntype Query {\n  _service: _Service\n  hello: String\n}\n\ntype _Service {\n  sdl: String\n}\n"
      }
    }
  }
  
  # Which expanding the `sdl` part:
  schema {
      query: Query
  }
  
  type Query {
      _service: _Service
      hello: String
  }
  
  type _Service {
      sdl: String
  }
  </code></pre>
  
  <p>So, they both are the same thing for defining how to get <code>sdl</code>, I checked into the microservice response, and found that graphene response is sending the correct data too, 
  with the Json response "data" being equal to:</p>
  
  <pre><code>execution_Result:  OrderedDict([('_service', OrderedDict([('sdl', 'schema {\n  query: Query\n}\n\ntype Query {\n  _service: _Service\n  hello: String\n}\n\ntype _Service {\n  sdl: String\n}\n')]))])
  </code></pre>
  
  <p>So what could the reason be for Apollo Federation not being able to successfully get this microservice schema?</p>