Skip to content
This repository has been archived by the owner on Sep 22, 2023. It is now read-only.

yeskiy/federation-with-subscriptions

 
 

Repository files navigation

Apollo Federation with Subscriptions

GitHub license npm version PRs Welcome

This library introduces subscriptions to Apollo Federation (which is currently not supported by apollo-server). Under the hood, it is using graphql-tools to convert the federation into schema-stitching SDL.

This library currently only works with express servers.

Installation

yarn add federation-with-subscriptions

Simple example

import {
  createGateway,
  createMicroservice,
} from "federation-with-subscriptions";
import { PubSub, withFilter } from "graphql-subscriptions";

const pubsub = new PubSub();

const usersMicroservice = () =>
  createMicroservice({
    label: "Users",
    port: 4001,
    typeDefs: `
      type User {
        id: ID!
        name: String!
      }

      type Query {
        users: [User!]!
      }
    `,
    resolvers: {
      Query: {
        users: () => [{ id: "1", name: "Sammy" }],
      },
    },
  });

const blogPostsMicroservice = () =>
  createMicroservice({
    label: "Blog Posts",
    port: 4002,
    context: ({ req }) => ({ headers: req.headers }),
    subscriptionContext: (ctx, message, args, headers) => ({ headers }),
    typeDefs: `
      type BlogPost {
        id: ID!
        title: String!
      }

      extend type User @key(fields: "id") {
        id: ID! @external
        blogPosts: [BlogPost!]!
      }

      type Mutation {
        updateBlogPost: BlogPost!
      }
			
      type Subscription {
        blogPostUpdates: BlogPost!
      }
    `,
    resolvers: {
      User: {
        blogPosts: () => [{ id: "44", title: "The Latest Post" }],
      },
      Mutation: {
        updateBlogPost: () => {
          const blogPost = {
            id: String(Math.random()),
            title: "A random post",
          };

          pubsub.publish("BLOG_POST_UPDATED", {
            blogPostUpdates: blogPost,
          });

          return blogPost;
        },
      },
      Subscription: {
        blogPostUpdates: {
          subscribe: withFilter(
            () => pubsub.asyncIterator(["BLOG_POST_UPDATED"]),
            (payload, variables, context) => {
              console.log({
                subscriptionContext: context,
              });

              return true;
            },
          ),
        },
      },
    },
  });

const main = async () => {
  const microservices = await Promise.all([
    usersMicroservice(),
    blogPostsMicroservice(),
  ]);

  const { expressApp } = await createGateway({
    microservices,
    port: 4000,

    // send some headers to subgraph microservices
    buildHttpHeaders: ({ req }) => ({
      "authorization": "Bearer secrettoken",
    }),
    buildSubscriptionHeaders: ({ connectionParams }) => ({
      "authorization": "Bearer secrettoken",
    }),
  });
};

main();

If you run the above in a Node.js environment, you can visit http://localhost:4000/graphql which will open the Apollo Studio.

Important: when testing using Apollo Studio, ensure that you switch the subscriptions implementation to graphql-ws:

Switch Apollo Studio ws implementation

{
  users {
    id
    name
     blogPosts {
       id
       title
     }
  }
}
subscription {
  blogPostUpdates {
     id
     title
  }
}
mutation {
  updateBlogPost {
    id
    title
  }
}

Subscriptions on the Frontend

Please checkout this repo and run yarn install & yarn start for a slightly more complex example including a full frontend integration.

License

federation-with-subscriptions is MIT licensed.

About

Apollo Federation with subscriptions support

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 99.0%
  • Other 1.0%