
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
graphql-component
Advanced tools
Build, customize and compose GraphQL schemas in a componentized fashion
A library for building modular and composable GraphQL schemas through a component-based architecture.
graphql-component
enables you to build GraphQL schemas progressively through a tree of components. Each component encapsulates its own schema, resolvers, and data sources, making it easier to build and maintain large GraphQL APIs.
Read more about the architecture principles in our blog post.
npm install graphql-component
const GraphQLComponent = require('graphql-component');
const { schema, context } = new GraphQLComponent({
types,
resolvers
});
A GraphQLComponent
instance creates a GraphQL schema in one of two ways:
makeExecutableSchema()
to generate a schema from local types/resolversTo create Apollo Federation subgraphs, set federation: true
in the component options:
const component = new GraphQLComponent({
types,
resolvers,
federation: true
});
This uses @apollo/federation
's buildSubgraphSchema()
instead of makeExecutableSchema()
.
new GraphQLComponent(options: IGraphQLComponentOptions)
types
: string | string[]
- GraphQL SDL type definitionsresolvers
: object
- Resolver map for the schemaimports
: Array<Component | ConfigObject>
- Components to importcontext
: { namespace: string, factory: Function }
- Context configurationmocks
: boolean | object
- Enable default or custom mocksdataSources
: Array<DataSource>
- Data source instancesdataSourceOverrides
: Array<DataSource>
- Override default data sourcesfederation
: boolean
- Enable Apollo Federation support (default: false
)pruneSchema
: boolean
- Enable schema pruning (default: false
)pruneSchemaOptions
: object
- Schema pruning optionstransforms
: Array<Transform>
- Schema transformation functionsinterface IGraphQLComponent {
readonly name: string;
readonly schema: GraphQLSchema;
readonly context: IContextWrapper;
readonly types: TypeSource;
readonly resolvers: IResolvers<any, any>;
readonly imports?: (IGraphQLComponent | IGraphQLComponentConfigObject)[];
readonly dataSources?: IDataSource[];
readonly dataSourceOverrides?: IDataSource[];
federation?: boolean;
}
class PropertyComponent extends GraphQLComponent {
constructor(options) {
super({
types,
resolvers,
...options
});
}
}
const { schema, context } = new GraphQLComponent({
imports: [
new PropertyComponent(),
new ReviewsComponent()
]
});
const server = new ApolloServer({ schema, context });
Data sources in graphql-component
use a proxy-based approach for context injection. The library provides two key types to assist with correct implementation:
// When implementing a data source:
class MyDataSource implements DataSourceDefinition<MyDataSource> {
name = 'MyDataSource';
// Context must be the first parameter when implementing
async getUserById(context: ComponentContext, id: string) {
// Use context for auth, config, etc.
return { id, name: 'User Name' };
}
}
// In resolvers, context is automatically injected:
const resolvers = {
Query: {
user(_, { id }, context) {
// Don't need to pass context - it's injected automatically
return context.dataSources.MyDataSource.getUserById(id);
}
}
}
// Add to component:
new GraphQLComponent({
types,
resolvers,
dataSources: [new MyDataSource()]
});
DataSourceDefinition<T>
: Interface for implementing data sources - methods must accept context as first parameterDataSource<T>
: Type representing data sources after proxy wrapping - context is automatically injectedThis type system ensures proper context handling while providing a clean API for resolver usage.
import {
GraphQLComponent,
DataSourceDefinition,
ComponentContext
} from 'graphql-component';
// Define your data source with proper types
class UsersDataSource implements DataSourceDefinition<UsersDataSource> {
name = 'users';
// Static property
defaultRole = 'user';
// Context is required as first parameter when implementing
async getUserById(context: ComponentContext, id: string): Promise<User> {
// Access context properties (auth, etc.)
const apiKey = context.config?.apiKey;
// Implementation details...
return { id, name: 'User Name', role: this.defaultRole };
}
async getUsersByRole(context: ComponentContext, role: string): Promise<User[]> {
// Implementation details...
return [
{ id: '1', name: 'User 1', role },
{ id: '2', name: 'User 2', role }
];
}
}
// In resolvers, the context is automatically injected
const resolvers = {
Query: {
user: (_, { id }, context) => {
// No need to pass context - it's injected by the proxy
return context.dataSources.users.getUserById(id);
},
usersByRole: (_, { role }, context) => {
// No need to pass context - it's injected by the proxy
return context.dataSources.users.getUsersByRole(role);
}
}
};
// Component configuration
const usersComponent = new GraphQLComponent({
types: `
type User {
id: ID!
name: String!
role: String!
}
type Query {
user(id: ID!): User
usersByRole(role: String!): [User]
}
`,
resolvers,
dataSources: [new UsersDataSource()]
});
You can override data sources when needed (for testing or extending functionality). The override must follow the same interface:
// For testing - create a mock data source
class MockUsersDataSource implements DataSourceDefinition<UsersDataSource> {
name = 'users';
defaultRole = 'admin';
async getUserById(context: ComponentContext, id: string) {
return { id, name: 'Mock User', role: this.defaultRole };
}
async getUsersByRole(context: ComponentContext, role: string) {
return [{ id: 'mock', name: 'Mock User', role }];
}
}
// Use the component with overrides
const testComponent = new GraphQLComponent({
imports: [usersComponent],
dataSourceOverrides: [new MockUsersDataSource()]
});
// In tests
const context = await testComponent.context({});
const mockUser = await context.dataSources.users.getUserById('any-id');
// mockUser will be { id: 'any-id', name: 'Mock User', role: 'admin' }
The repository includes example implementations:
npm run start-composition
npm run start-federation
Both examples are accessible at http://localhost:4000/graphql
Enable debug logging with:
DEBUG=graphql-component:* node your-app.js
src/
- Core library codeexamples/
composition/
- Schema composition examplefederation/
- Federation implementation examplePlease read our contributing guidelines (link) for details on our code of conduct and development process.
This project is licensed under the MIT License - see the LICENSE file for details.
FAQs
Build, customize and compose GraphQL schemas in a componentized fashion
The npm package graphql-component receives a total of 0 weekly downloads. As such, graphql-component popularity was classified as not popular.
We found that graphql-component demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.