apollographql / apollographql/federation
Request: Create standard means for generating local schema file for ease of CICD federation deployment
- 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
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