Skip to content

Commit

Permalink
Refactor validateSatisfiability to accept either a schema or sdl (#…
Browse files Browse the repository at this point in the history
…3033)

<!--
First, 🌠 thank you 🌠 for taking the time to consider a contribution to
Apollo!

Here are some important details to follow:

* ⏰ Your time is important
To save your precious time, if the contribution you are making will
take more than an hour, please make sure it has been discussed in an
        issue first. This is especially true for feature requests!

* 💡 Features
Feature requests can be created and discussed within a GitHub Issue.
Be sure to search for existing feature requests (and related issues!)
prior to opening a new request. If an existing issue covers the need,
please upvote that issue by using the 👍 emote, rather than opening a
        new issue.

* 🕷 Bug fixes
These can be created and discussed in this repository. When fixing a
bug,
please _try_ to add a test which verifies the fix. If you cannot, you
should
still submit the PR but we may still ask you (and help you!) to create a
test.

* Federation versions
Please make sure you're targeting the federation version you're opening
the PR for. Federation 2 (alpha) is currently located on the `main`
branch and prior versions of Federation live on the `version-0.x`
branch.

* 📖 Contribution guidelines
Follow
https://github.com/apollographql/federation/blob/HEAD/CONTRIBUTING.md
when submitting a pull request. Make sure existing tests still pass, and
add
        tests for all new behavior.

* ✏️ Explain your pull request
Describe the big picture of your changes here to communicate to what
        your pull request is meant to accomplish. Provide 🔗 links 🔗 to
        associated issues!

We hope you will find this to be a positive experience! Open source
contribution can be intimidating and we hope to alleviate that pain as
much
as possible. Without following these guidelines, you may be missing
context
that can help you succeed with your contribution, which is why we
encourage
discussion first. Ultimately, there is no guarantee that we will be able
to
merge your pull-request, but by following these guidelines we can try to
avoid disappointment.

-->
  • Loading branch information
tayrrible authored Jun 12, 2024
1 parent 11ffbcd commit 8343937
Showing 1 changed file with 41 additions and 11 deletions.
52 changes: 41 additions & 11 deletions composition-js/src/compose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,29 @@ function validateCompositionOptions(options: CompositionOptions) {
assert(!options?.allowedFieldTypeMergingSubtypingRules?.includes("list_upgrade"), "The `list_upgrade` field subtyping rule is currently not supported");
}

export function compose(subgraphs: Subgraphs, options: CompositionOptions = {}): CompositionResult {
/**
* Used to compose a supergraph from subgraphs
*
* @param subgraphs Subgraphs
* @param options CompositionOptions
* @param runSatisfiability Boolean - flag used to toggle satisfiability. Defaults to `true`
*/
export function compose(subgraphs: Subgraphs, options: CompositionOptions = {}, runSatisfiability = true): CompositionResult {
validateCompositionOptions(options);

const mergeResult = validateSubgraphsAndMerge(subgraphs);
if (mergeResult.errors) {
return { errors: mergeResult.errors };
}

const satisfiabilityResult = validateSatisfiability(
mergeResult.supergraph
);
if (satisfiabilityResult.errors) {
return { errors: satisfiabilityResult.errors };
let satisfiabilityResult;
if (runSatisfiability) {
satisfiabilityResult = validateSatisfiability({
supergraphSchema: mergeResult.supergraph
});
if (satisfiabilityResult.errors) {
return { errors: satisfiabilityResult.errors };
}
}

// printSchema calls validateOptions, which can throw
Expand All @@ -74,11 +84,19 @@ export function compose(subgraphs: Subgraphs, options: CompositionOptions = {}):
return {
schema: mergeResult.supergraph,
supergraphSdl,
hints: [...mergeResult.hints, ...(satisfiabilityResult.hints ?? [])],
hints: [...mergeResult.hints, ...(satisfiabilityResult?.hints ?? [])],
};
}

export function composeServices(services: ServiceDefinition[], options: CompositionOptions = {}): CompositionResult {
/**
* Method to validate and compose services
*
* @param services List of Service definitions
* @param options CompositionOptions
* @param runSatisfiability Flag to toggle satisfiability check within composition. Defaults to `true`
* @returns CompositionResult
*/
export function composeServices(services: ServiceDefinition[], options: CompositionOptions = {}, runSatisfiability = true): CompositionResult {
const subgraphs = subgraphsFromServiceList(services);
if (Array.isArray(subgraphs)) {
// Errors in subgraphs are not truly "composition" errors, but it's probably still the best place
Expand All @@ -87,17 +105,29 @@ export function composeServices(services: ServiceDefinition[], options: Composit
return { errors: subgraphs };
}

return compose(subgraphs, options);
return compose(subgraphs, options, runSatisfiability);
}

export function validateSatisfiability(supergraphSchema: Schema) : {
type SatisfiabilityArgs = {
supergraphSchema: Schema
supergraphSdl?: never
} | { supergraphSdl: string, supergraphSchema?: never };

/**
* Run satisfiability check for a supergraph
*
* Can pass either the supergraph's Schema or SDL to validate
* @param args: SatisfiabilityArgs
* @returns { errors? : GraphQLError[], hints? : CompositionHint[] }
*/
export function validateSatisfiability({ supergraphSchema, supergraphSdl} : SatisfiabilityArgs) : {
errors? : GraphQLError[],
hints? : CompositionHint[],
} {
// We pass `null` for the `supportedFeatures` to disable the feature support validation. Validating feature support
// is useful when executing/handling a supergraph, but here we're just validating the supergraph we've just created,
// and there is no reason to error due to an unsupported feature.
const supergraph = new Supergraph(supergraphSchema, null);
const supergraph = supergraphSchema ? new Supergraph(supergraphSchema, null) : Supergraph.build(supergraphSdl);
const supergraphQueryGraph = buildSupergraphAPIQueryGraph(supergraph);
const federatedQueryGraph = buildFederatedQueryGraph(supergraph, false);
return validateGraphComposition(supergraph.schema, supergraph.subgraphNameToGraphEnumValue(), supergraphQueryGraph, federatedQueryGraph);
Expand Down

0 comments on commit 8343937

Please sign in to comment.