apollographql / apollographql/federation

Request: Create standard means for generating local schema file for ease of CICD federation deployment

Open
#330 0 comments 2 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
725
Forks
276
Avg merge
1h 47m
Merged PRs (30d)
1

Description

I'm currently trying to integrate our service infrastructure using managed federation, and am building out our CICD tooling for our various services. My first attempt was to just use introspection via the --endpoint option for apollo service:push. Unfortunately, this because pretty arduous and hacky in our CICD pipeline pre/post deployment. I eventually decided that generating a schema file would be an easier approach.

Unfortunately, these services use varying technologies and don't all pull directly from a simple schema.gql file. They do all eventually implement typeDefs that I can import, in order to spin up their own Apollo Server instances. My new build process would be

```
1. Generate a localSchema file
2. Check against the various environments using that file
3. Deploy the service
4. Push the localSchema file/service to the managed federation
```

The main problem that I was running into is that the schema files that I could easily generate include all the apollo directives, the _Schema query, etc. As a result, calling apollo service:push would fail. I tried hacking out the various directives, but was really struggling with the _Schema being added to the query, and felt like I ultimately was getting even more hacky than using introspection in our CI/CD pipeline.

I ended up eventually getting something that seems to work for pushing up our APIs, but I'm wary of using it, because it seems pretty outside the use case that these functions are used for. Am I missing something? There has to be a simpler way ... and if not, if there is any way to create some sort of tooling within the apollo framework to make generating a local schema file a bit easier? Here's my first pass at it.

```
const { normalizeTypeDefs } = require('@apollo/federation/dist/composition/normalize');
const { buildSchemaFromDefinitionsAndExtensions, buildMapsFromServiceList } = require('@apollo/federation/dist/composition/compose');
const { printSchema } = require('graphql');
const fs = require('fs');

const { typeDefs } = require('../graphql/schema'); // My actual typeDefs are exported here

const strippedTypeDefs = normalizeTypeDefs(typeDefs);
const {
typeDefinitionsMap,
typeExtensionsMap,
directiveDefinitionsMap,
} = buildMapsFromServiceList([{ name: 'serviceName', typeDefs: strippedTypeDefs }]);

const { schema } = buildSchemaFromDefinitionsAndExtensions({
typeDefinitionsMap,
typeExtensionsMap,
directiveDefinitionsMap,
});

try {
// I'm saving the generated schema.gql (that has removed the federation directives, etc)
fs.writeFile('federated/schema.gql', printSchema(schema), (err) => {
if (err) throw err;
console.log('Generated schema -- see federated/schema.gql');
});
} catch (err) {
console.log(`Unable to generate schema: ${err.message}`);
}

```

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the federation composition entry points mentioned in the issue: normalizeTypeDefs, buildMapsFromServiceList, buildSchemaFromDefinitionsAndExtensions, and printSchema. Define a supported way to generate a local schema from imported typeDefs without federation directives or the _Schema query, then verify that the resulting file can be used for environment checks and managed federation pushes.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, typescript
Domain
api, ci-cd, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.