idio-graphql
This package is inspired by; Apollo Federation, GraphQL Modules & Moleculer.
About
Node.js library for splitting SDL first GraphQL schemas into composable & idiomatic chunks.
Installation
$ npm install idio-graphql
⚠ graphql
is a peerDependency you may need to install this too.
$ npm install graphql
Usage
const User = name: "User" typeDefs: ` type User { id: ID name: String age: Int } type Query { user(id: ID!): User } ` resolvers: Query: ... ; const typeDefs resolvers = ; const server = typeDefs resolvers ;
Index
Examples
- Monolith
- Microservice
- Mini examples - Some smaller examples to help demonstrate the capability's of this package.
FAQ
- What is a node ?
- How do I integrate with my Apollo Server ?
- How do I get started with microservices ?
- Can I use Schema Directives ?
- How can my nodes talk with each other ?
- Does it support graphql files or graphql tag ?
- What is the role of the gateway ?
- Does it support subscriptions ?
What is a node ?
A Node is designed to modularize a ObjectTypeDefinition together with its related resolvers & properties. You can think of a node as a module.
const User = name: "User" typeDefs: ` type User ... type Query { getUser: User } ` resolvers: Query: { ... } ;
You can compose nodes
const Comment = name: "Comment" ...; const Post = name: "Post" nodes: Comment ...; const User = name: "User" nodes: Post ...;
Is it all about nodes ? There are plenty of classes to help you construct your GraphQL schema start reading about schemaAppliances here.
How do I integrate with my Apollo Server ?
The result of makeExecutableSchema
is returned from combineNodes
& GraphQLSchema
.
Using combineNodes
const typeDefs resolvers = ; const apolloServer = typeDefs resolvers ;
Using GraphQLGateway
const gateway = services: nodes: "User" transporter: "redis://localhost" nodeID: "gateway" ; const typeDefs resolvers = await gatewaystart; const apolloServer = typeDefs resolvers ;
How do I get started with microservices ?
Watch tutorial here
This package builds its microservices features on top of a package Molecular, this means you can integrate with Moleculer's features. Learn more about using microservices here.
Molecular is a optional dependency
const User = name: "User"; await User;
Do not forget to create your gateway
Gradual Adoption
You don't need have to have all your nodes as a service. You can have some nodes hosted on the same instance as the gateway. Use locals
& services
in GraphQLGateway to merge all nodes together. Read more about gradual adoption here.
Can I use Schema Directives ?
You can use a IdioDirective and apply it at combineNodes
or GraphQLGateway
.
const MyDirective = name: "..." typeDefs: ` ... ` resolver: SchemaDirectiveVisitor; const typeDefs resolvers schemaDirectives = ;
How can my nodes talk with each other ?
Inter-Schema Execution can be used to make GraphQL powered Queries & Mutations against your own or specified schema.
Inter-Schema Execution works with your served nodes, this will allow you to accomplish GraphQL powered service-service communication.
const Post = name: "Post" typeDefs: ` type Post { title: String } type Query { posts: [Post] } ` resolvers: ... ; const User = name: "User" typeDefs: ` type User { posts: [Post] } ` resolvers: Fields: posts: async { const data errors = await injections; return dataposts; } ;
Does it support graphql files or graphql tag ?
When specifying typedefs
You can use; strings, graphql-tag or file paths
What is the role of the gateway ?
Remember the initial schema & keep track of services with the corresponding names. Produce a Graphql schema after introspecting each supplied service.
GraphQLGateway
acts as a reverse proxy when using Inter-Schema execution.
Your gateway will;
- Not throw if it loses connection to a service
- Allow unlimited services, with the same name, to join the swarm
- Load balance requests to each service
- Not start until all services are connected
- Ensure no other gateway has the same name but different schema
You can spawn multiple instances of the same gateway
Does it support subscriptions ?
You can setup subscriptions in a node. Subscriptions will work with microservices.
const User = name: "User" typeDefs: ` type User ... type Subscription { userUpdate: User } ` resolvers: Subscription: userUpdate: {} // AsyncGenerator ;
Subscriptions will not work service-service communication.
Quick Start
$ npm install idio-graphql apollo-server graphql-tag
const combineNodes GraphQLNode } = ; const ApolloServer = ;const gql = ; const User = name: "User" typeDefs: gql` type User { id: ID name: String age: Int } type Query { user(id: ID!): User } ` resolvers: Query: { ... } ; { const typeDefs resolvers = ; const server = typeDefs resolvers ; await server; console;} ;
Microservices Quick Start
Requires nats-server @ nats://localhost:4222
$ npm install idio-graphql apollo-server graphql-tag moleculer nats
User Service
const gql = ;const GraphQLNode = ; const User = name: "User" typeDefs: gql` type User { id: String name: String age: Int } type Query { user(id: String!): User } ` resolvers: Query: { ... } ; await User;
Gateway Service
const ApolloServer = ;const GraphQLGateway = ; const gateway = services: nodes: "User" transporter: "NATS" nodeID: "gateway" ; const typeDefs resolvers = await gatewaystart; const server = typeDefs resolvers; await server;