Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add supergraph endpoint #189

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

agologan
Copy link

Problem

In order to use Apollo Router #162 one needs a composed supergraph to provide to it.
While this can be done using Rover CLI or via @apollo/composition it's not very easy to do it and may require an extra infrastructure component.

Changes

New /schema/supegraph that can be passed directly to the router.
Endpoint is cached in memory (without other deps), and is invalidated on subgraph changes.

Example Helm values for Apollo Router:

router:
  args:
    - --hot-reload
    - -s
    - /tmp/supergraph.graphql
extraContainers:
  - name: update-graph
    image: quay.io/curl/curl:8.4.0
    command: ["watch"]
    args: ["-n", "60", "curl", "-v", "http://graphql-schema-registry/schema/supergraph", "-o", "/tmp/supergraph.graphql"]
    volumeMounts:
    - name: schema
      mountPath: /tmp/
extraVolumes:
  - name: schema
    emptyDir: {}
extraVolumeMounts:
  - name: schema
    mountPath: /tmp/
    readOnly: true

@agologan agologan force-pushed the supergraph-endpoint branch from 5738ead to bdb6578 Compare October 31, 2023 14:32
@tot-ra
Copy link
Owner

tot-ra commented Dec 4, 2023

hey @agologan . Thanks for the effort. How is supergraph different from GET /schema/latest ? Is it because of text/plain.. or different format?
Also, some tests would be nice

@agologan
Copy link
Author

router.get('/schema/latest', asyncWrap(schema.composeLatest));
export async function composeLatest(req, res) {
	const schema = await getAndValidateSchema(connection, false, false);

	return res.json({
		success: true,
		data: schema,
	});
}

At a quick glance it just returns the schema wrapper in JSON object, but looking further..

export async function getAndValidateSchema(
	trx,
	services = false,
	validate = true
) {
	const schemas = services
		? await schemaModel.getSchemaByServiceVersions({ trx, services })
		: await schemaModel.getLastUpdatedForActiveServices({ trx });

	logger.info(
		'Validating schema. Got services schemas from DB transaction..',
		{
			schemas,
		}
	);

	if (validate && schemas && schemas.length) {
		federationHelper.composeAndValidateSchema(schemas);
	}

	return schemas;
}

So getAndValidateSchema composes the schema for validation but throws away the composition (supergraph) and in turns returns a list of schemas.

Put together GET /schema/latest returns a json object indicating composition success and the list of schemas that would make up the supergraph.
One can also see this in the examples where the gateway needs to compose the graph i.e. https://github.com/tot-ra/graphql-schema-registry/blob/master/examples/gateway_service_hard_coded_urls/supergraph.js#L88

By comparison, the new endpoint composes, caches and returns the supergraph to be used directly in a gateway or router.

In case of Apollo Router it does not do it's own composition as seen here https://www.apollographql.com/docs/router/migrating-from-gateway#servicelist--introspectandcompose
So if one wanted to use it they'd either have to add another infrastructure component to do the composition or have the registry do it since it already runs that code but it throws away the result.

@tot-ra
Copy link
Owner

tot-ra commented Dec 30, 2023

please add tests and examples of how its used

@agologan agologan requested a review from tot-ra as a code owner March 13, 2024 23:27
@agologan
Copy link
Author

agologan commented Mar 13, 2024

Added a sanity test to schema.itest.ts to ensure composition works.
Added new tests to router/index.itest.ts using supertest which call via express router testing the caching layer as well.

LE: Provided a working compose example and updated the examples docs. See: 34ab51a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants