npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

federation-to-stitching-sdl

v1.0.1

Published

This utility converts an [Apollo Federation SDL](https://www.apollographql.com/docs/federation/federation-spec/) string into a [Schema Stitching SDL](https://www.graphql-tools.com/docs/stitch-directives-sdl/) string. Schema Stitching supports freeform ser

Downloads

28

Readme

Federation SDL to Stitching SDL

This utility converts an Apollo Federation SDL string into a Schema Stitching SDL string. Schema Stitching supports freeform service bindings that may integrate with any GraphQL query, including the _entities query setup by Federation services. That means any Federation SDL may be converted to a Stitching SDL and added to a stitched gateway...

Federation SDL:

type Widget @key(fields: 'id') {
  id: ID! @external
  name: String
  price: Int @external
  shippingCost: Int @requires(fields: 'price')
  parent: Widget @provides(fields: 'price')
}

converted Stitching SDL:

type Widget @key(selectionSet: '{ id }') {
  id: ID!
  name: String
  shippingCost: Int @computed(selectionSet: '{ price }')
  parent: Widget
}

scalar _Any
union _Entity = Widget

type Query {
  _entities(representations: [_Any!]!): [_Entity]! @merge
}

The translated SDL is configured for the Schema Stitching query planner, see complete translation logic summary below.

Usage

Install the package:

npm install federation-to-stitching-sdl

Fetch the SDL from a Federation service:

query {
  _service {
    sdl
  }
}

Convert the Federation SDL to a Stitching SDL:

const federationToStitchingSDL = require('federation-to-stitching-sdl');
const { stitchingDirectives } = require('@graphql-tools/stitching-directives');

// config is only needed when customizing stitching directive names...
const config = stitchingDirectives();
const stitchingSDL = federationToStitchingSDL(federationSDL, config);

Example

A working example can be found in the Schema Stitching Handbook. A compact summary of the major parts looks like this:

const federationToStitchingSDL = require('federation-to-stitching-sdl');
const { stitchSchemas } = require('@graphql-tools/stitch');
const { stitchingDirectives } = require('@graphql-tools/stitching-directives');
const { buildSchema, print } = require('graphql');
const { fetch } = require('cross-fetch');
const stitchingConfig = stitchingDirectives();

const executor = async ({ document, variables }) => {
  const query = typeof document === 'string' ? document : print(document);
  const result = await fetch('http://localhost:4001/graphql', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, variables }),
  });
  return result.json();
};

const federationSDL = await executor({ document: '{ _service { sdl } }' });
const stitchingSDL = federationToStitchingSDL(federationSDL, stitchingConfig);

const gatewaySchema = stitchSchemas({
  subschemaConfigTransforms: [stitchingConfig.stitchingDirectivesTransformer],
  subschemas: [{
    schema: buildSchema(stitchingSDL),
    executor
  }]
});

Translation logic

Federation and Stitching use fundamentally similar patterns to combine underlying subservices (in fact, both tools have shared origins in Apollo Stitching). However, Federation SDLs are nuanced because they are incomplete (they omit their own spec), they may contain baseless type extensions (which are invalid GraphQL), and they may contain fields that the service has no data for (the "external" fields). These nuances are normalized for Schema Stitching as follows:

  1. Prepend a directives type definition string.
  2. Turn all baseless type extensions into base types.
  3. Rewrite @key(fields: "id") as @key(selectionSet: "{ id }").
  4. Rewrite @requires(fields: "price") as @computed(selectionSet: "{ price }").
  5. Remove fields with an @external directive unless they are part of the @key. Stitching expects schemas to only publish fields that they actually have data for. Remove any remaining @external directives.
  6. Remove all @provides directives. They are no longer necessary once the indirection of @external fields is eliminated. Stitching's query planner can automate the optimial selection of as many fields as possible from as few services as possible.
  7. Collect the names of all types marked with @key (Entities). If there are one or more names:
    • Add an _Any scalar.
    • Add an _Entity union populated with all unique names.
    • Add an _entities(representations: [_Any!]!): [_Entity]! @merge query.